0028222: Intersection of two cylinders fails
[occt.git] / src / IntPatch / IntPatch_Intersection.cxx
1 // Created by: Modelization
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <stdio.h>
16 #include <IntPatch_Intersection.hxx>
17
18 #include <Adaptor3d_HSurface.hxx>
19 #include <Adaptor3d_TopolTool.hxx>
20 #include <IntPatch_ALine.hxx>
21 #include <IntPatch_ALineToWLine.hxx>
22 #include <IntPatch_GLine.hxx>
23 #include <IntPatch_ImpImpIntersection.hxx>
24 #include <IntPatch_ImpPrmIntersection.hxx>
25 #include <IntPatch_PrmPrmIntersection.hxx>
26 #include <IntPatch_WLine.hxx>
27 #include <IntPatch_WLineTool.hxx>
28
29 #include <ProjLib_ProjectOnPlane.hxx>
30 #include <Geom_Plane.hxx>
31 #include <GeomAdaptor_HSurface.hxx>
32 #include <GeomAdaptor_HCurve.hxx>
33 #include <ProjLib_ProjectedCurve.hxx>
34 #include <Geom2dInt_GInter.hxx>
35 #include <Geom2dAdaptor_Curve.hxx>
36 #include <ProjLib.hxx>
37
38 //======================================================================
39 // function: SequenceOfLine
40 //======================================================================
41 const IntPatch_SequenceOfLine& IntPatch_Intersection::SequenceOfLine() const { return(slin); }
42
43 //======================================================================
44 // function: IntPatch_Intersection
45 //======================================================================
46 IntPatch_Intersection::IntPatch_Intersection ()
47  : done(Standard_False),
48    //empt, tgte, oppo,
49    myTolArc(0.0), myTolTang(0.0),
50    myUVMaxStep(0.0), myFleche(0.0),
51    myIsStartPnt(Standard_False)
52    //myU1Start, myV1Start, myU2Start, myV2Start
53 {
54 }
55
56 //======================================================================
57 // function: IntPatch_Intersection
58 //======================================================================
59 IntPatch_Intersection::IntPatch_Intersection(const Handle(Adaptor3d_HSurface)&  S1,
60                                              const Handle(Adaptor3d_TopolTool)& D1,
61                                              const Handle(Adaptor3d_HSurface)&  S2,
62                                              const Handle(Adaptor3d_TopolTool)& D2,
63                                              const Standard_Real TolArc,
64                                              const Standard_Real TolTang)
65  : done(Standard_False),
66    //empt, tgte, oppo,
67    myTolArc(TolArc), myTolTang(TolTang),
68    myUVMaxStep(0.0), myFleche(0.0),
69    myIsStartPnt(Standard_False)
70    //myU1Start, myV1Start, myU2Start, myV2Start
71 {
72   if(myTolArc<1e-8) myTolArc=1e-8;
73   if(myTolTang<1e-8) myTolTang=1e-8;
74   if(myTolArc>0.5) myTolArc=0.5;
75   if(myTolTang>0.5) myTolTang=0.5;
76   Perform(S1,D1,S2,D2,TolArc,TolTang);
77 }
78
79 //======================================================================
80 // function: IntPatch_Intersection
81 //======================================================================
82 IntPatch_Intersection::IntPatch_Intersection(const Handle(Adaptor3d_HSurface)&  S1,
83                                              const Handle(Adaptor3d_TopolTool)& D1,
84                                              const Standard_Real TolArc,
85                                              const Standard_Real TolTang)
86  : done(Standard_False),
87    //empt, tgte, oppo,
88    myTolArc(TolArc), myTolTang(TolTang),
89    myUVMaxStep(0.0), myFleche(0.0),
90    myIsStartPnt(Standard_False)
91    //myU1Start, myV1Start, myU2Start, myV2Start
92 {
93   Perform(S1,D1,TolArc,TolTang);
94 }
95
96 //======================================================================
97 // function: SetTolerances
98 //======================================================================
99 void IntPatch_Intersection::SetTolerances(const Standard_Real TolArc,
100                                           const Standard_Real TolTang,
101                                           const Standard_Real UVMaxStep,
102                                           const Standard_Real Fleche)
103
104   myTolArc     = TolArc;
105   myTolTang    = TolTang;
106   myUVMaxStep  = UVMaxStep;
107   myFleche     = Fleche;
108   if(myTolArc<1e-8) myTolArc=1e-8;
109   if(myTolTang<1e-8) myTolTang=1e-8;
110   if(myTolArc>0.5) myTolArc=0.5;
111   if(myTolTang>0.5) myTolTang=0.5;  
112   if(myFleche<1.0e-3) myFleche=1e-3;
113   if(myUVMaxStep<1.0e-3) myUVMaxStep=1e-3;
114   if(myFleche>10) myFleche=10;
115   if(myUVMaxStep>0.5) myUVMaxStep=0.5;
116 }
117
118 //======================================================================
119 // function: Perform
120 //======================================================================
121 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
122                                     const Handle(Adaptor3d_TopolTool)& D1,
123                                     const Standard_Real TolArc,
124                                     const Standard_Real TolTang)
125 {
126   myTolArc = TolArc;
127   myTolTang = TolTang;
128   if(myFleche == 0.0)  myFleche = 0.01;
129   if(myUVMaxStep==0.0) myUVMaxStep = 0.01;
130
131   done = Standard_True;
132   spnt.Clear();
133   slin.Clear();
134   
135   empt = Standard_True;
136   tgte = Standard_False;
137   oppo = Standard_False;
138
139   switch (S1->GetType())
140   { 
141   case GeomAbs_Plane:
142   case GeomAbs_Cylinder:
143   case GeomAbs_Sphere:
144   case GeomAbs_Cone:
145   case GeomAbs_Torus:
146     break;
147   case GeomAbs_SurfaceOfExtrusion:
148     {
149       gp_Dir aDirection = S1->Direction();
150       gp_Ax3 anAxis(gp::Origin(), aDirection);
151       Handle(Adaptor3d_HCurve) aBasisCurve = S1->BasisCurve();
152       ProjLib_ProjectOnPlane Projector(anAxis);
153       Projector.Load(aBasisCurve, Precision::Confusion());
154       Handle(GeomAdaptor_HCurve) aProjCurve = Projector.GetResult();
155       Handle(Geom_Plane) aPlane = new Geom_Plane(anAxis);
156       Handle(GeomAdaptor_HSurface) aGAHsurf = new GeomAdaptor_HSurface(aPlane);
157       ProjLib_ProjectedCurve aProjectedCurve(aGAHsurf, aProjCurve);
158       Handle(Geom2d_Curve) aPCurve;
159       ProjLib::MakePCurveOfType(aProjectedCurve, aPCurve);
160       Geom2dAdaptor_Curve AC(aPCurve,
161                              aProjectedCurve.FirstParameter(),
162                              aProjectedCurve.LastParameter());
163       Geom2dInt_GInter Intersector(AC,
164                                    Precision::Confusion(),
165                                    Precision::Confusion());
166       if (Intersector.IsDone() && Intersector.IsEmpty())
167         break;
168     }
169   default:
170     {
171       IntPatch_PrmPrmIntersection interpp;
172       interpp.Perform(S1,D1,TolTang,TolArc,myFleche,myUVMaxStep);
173       if (interpp.IsDone())
174       {
175         done = Standard_True;
176         tgte = Standard_False;
177         empt = interpp.IsEmpty();
178         const Standard_Integer nblm = interpp.NbLines();
179         for (Standard_Integer i=1; i<=nblm; i++) slin.Append(interpp.Line(i));
180       }
181     }
182     break;
183   }
184 }
185
186 /////////////////////////////////////////////////////////////////////////////
187 //  These several support functions provide methods which can help basic   //
188 //  algorithm to intersect infinite surfaces of the following types:       //
189 //                                                                         //
190 //  a.) SurfaceOfExtrusion;                                                //
191 //  b.) SurfaceOfRevolution;                                               //
192 //  c.) OffsetSurface.                                                     //
193 //                                                                         //
194 /////////////////////////////////////////////////////////////////////////////
195 #include <TColgp_Array1OfXYZ.hxx>
196 #include <TColgp_Array1OfPnt.hxx>
197 #include <TColgp_SequenceOfPnt.hxx>
198 #include <Extrema_ExtPS.hxx>
199 #include <Extrema_POnSurf.hxx>
200 #include <Geom2d_Curve.hxx>
201 #include <Geom2dAPI_InterCurveCurve.hxx>
202 #include <GeomAdaptor.hxx>
203 #include <GeomAdaptor_HCurve.hxx>
204 #include <GeomAdaptor_Curve.hxx>
205 #include <GeomAdaptor_Surface.hxx>
206 #include <GeomAdaptor_HSurface.hxx>
207 #include <Geom_Plane.hxx>
208 #include <ProjLib_ProjectOnPlane.hxx>
209 #include <GeomProjLib.hxx>
210 #include <ElCLib.hxx>
211 #include <Geom_TrimmedCurve.hxx>
212 #include <Geom_Surface.hxx>
213 #include <Geom_SurfaceOfLinearExtrusion.hxx>
214 #include <Geom_OffsetSurface.hxx>
215 #include <Geom_SurfaceOfRevolution.hxx>
216 #include <Geom_RectangularTrimmedSurface.hxx>
217
218 //===============================================================
219 //function: FUN_GetMinMaxXYZPnt
220 //===============================================================
221 static void FUN_GetMinMaxXYZPnt( const Handle(Adaptor3d_HSurface)& S,
222                                  gp_Pnt& pMin, gp_Pnt& pMax )
223 {
224   const Standard_Real DU = 0.25 * Abs(S->LastUParameter() - S->FirstUParameter());
225   const Standard_Real DV = 0.25 * Abs(S->LastVParameter() - S->FirstVParameter());
226   Standard_Real tMinXYZ = RealLast();
227   Standard_Real tMaxXYZ = -tMinXYZ;
228   gp_Pnt PUV, ptMax, ptMin;
229   for(Standard_Real U = S->FirstUParameter(); U <= S->LastUParameter(); U += DU)
230   {
231     for(Standard_Real V = S->FirstVParameter(); V <= S->LastVParameter(); V += DV)
232     {
233       S->D0(U,V,PUV);
234       const Standard_Real cXYZ = PUV.XYZ().Modulus();
235       if(cXYZ > tMaxXYZ) { tMaxXYZ = cXYZ; ptMax = PUV; }
236       if(cXYZ < tMinXYZ) { tMinXYZ = cXYZ; ptMin = PUV; }
237     }
238   }
239   pMin = ptMin;
240   pMax = ptMax;
241 }
242 //==========================================================================
243 //function: FUN_TrimInfSurf
244 //==========================================================================
245 static void FUN_TrimInfSurf(const gp_Pnt& Pmin,
246                             const gp_Pnt& Pmax,
247                             const Handle(Adaptor3d_HSurface)& InfSurf,
248                             const Standard_Real& AlternativeTrimPrm,
249                             Handle(Adaptor3d_HSurface)& TrimS)
250 {
251   Standard_Real TP = AlternativeTrimPrm;
252   Extrema_ExtPS ext1(Pmin, InfSurf->Surface(), 1.e-7, 1.e-7);
253   Extrema_ExtPS ext2(Pmax, InfSurf->Surface(), 1.e-7, 1.e-7);
254   if(ext1.IsDone() || ext2.IsDone())
255   {
256     Standard_Real Umax = -1.e+100, Umin = 1.e+100, Vmax = -1.e+100, Vmin = 1.e+100, cU, cV;
257     if(ext1.IsDone())
258     {
259       for(Standard_Integer i = 1; i <= ext1.NbExt(); i++)
260       {
261         const Extrema_POnSurf & pons = ext1.Point(i);
262         pons.Parameter(cU,cV);
263         if(cU > Umax) Umax = cU;
264         if(cU < Umin) Umin = cU;
265         if(cV > Vmax) Vmax = cV;
266         if(cV < Vmin) Vmin = cV;
267       }
268     }
269     if(ext2.IsDone())
270     {
271       for(Standard_Integer i = 1; i <= ext2.NbExt(); i++)
272       {
273         const Extrema_POnSurf & pons = ext2.Point(i);
274         pons.Parameter(cU,cV);
275         if(cU > Umax) Umax = cU;
276         if(cU < Umin) Umin = cU;
277         if(cV > Vmax) Vmax = cV;
278         if(cV < Vmin) Vmin = cV;
279       }
280     }
281     TP = Max(Abs(Umin),Max(Abs(Umax),Max(Abs(Vmin),Abs(Vmax))));
282   }
283   if(TP == 0.) { TrimS = InfSurf; return; }
284   else
285   {
286     const Standard_Boolean Uinf = Precision::IsNegativeInfinite(InfSurf->FirstUParameter()); 
287     const Standard_Boolean Usup = Precision::IsPositiveInfinite(InfSurf->LastUParameter());
288     const Standard_Boolean Vinf = Precision::IsNegativeInfinite(InfSurf->FirstVParameter()); 
289     const Standard_Boolean Vsup = Precision::IsPositiveInfinite(InfSurf->LastVParameter());
290     Handle(Adaptor3d_HSurface) TmpSS;
291     Standard_Integer IsTrimed = 0;
292     const Standard_Real tp = 1000.0 * TP;
293     if(Vinf && Vsup) { TrimS = InfSurf->VTrim(-tp, tp, 1.0e-7); IsTrimed = 1; }
294     if(Vinf && !Vsup){ TrimS = InfSurf->VTrim(-tp, InfSurf->LastVParameter(), 1.0e-7); IsTrimed = 1; }
295     if(!Vinf && Vsup){ TrimS = InfSurf->VTrim(InfSurf->FirstVParameter(), tp, 1.0e-7); IsTrimed = 1; }
296     if(IsTrimed)
297     {
298       TmpSS = TrimS;
299       if(Uinf && Usup)  TrimS = TmpSS->UTrim(-tp, tp, 1.0e-7);
300       if(Uinf && !Usup) TrimS = TmpSS->UTrim(-tp, InfSurf->LastUParameter(), 1.0e-7);
301       if(!Uinf && Usup) TrimS = TmpSS->UTrim(InfSurf->FirstUParameter(), tp, 1.0e-7);
302     }
303     else
304     {
305       if(Uinf && Usup)  TrimS = InfSurf->UTrim(-tp, tp, 1.0e-7);
306       if(Uinf && !Usup) TrimS = InfSurf->UTrim(-tp, InfSurf->LastUParameter(), 1.0e-7);
307       if(!Uinf && Usup) TrimS = InfSurf->UTrim(InfSurf->FirstUParameter(), tp, 1.0e-7);
308     }
309   }
310 }
311 //================================================================================
312 //function: FUN_GetUiso
313 //================================================================================
314 static void FUN_GetUiso(const Handle(Geom_Surface)& GS,
315                         const GeomAbs_SurfaceType&  T,
316                         const Standard_Real&        FirstV,
317                         const Standard_Real&        LastV,
318                         const Standard_Boolean&     IsVC,
319                         const Standard_Boolean&     IsVP,
320                         const Standard_Real&        U,
321                         Handle(Geom_Curve)&         I)
322 {
323   if(T !=  GeomAbs_OffsetSurface)
324   {
325     Handle(Geom_Curve) gc = GS->UIso(U);
326     if(IsVP && (FirstV == 0.0 && LastV == (2.*M_PI))) I = gc;
327     else
328     {
329       Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstV,LastV);
330       //szv:I = Handle(Geom_Curve)::DownCast(gtc);
331       I = gtc;
332     }
333   }
334   else//OffsetSurface
335   {
336     const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (GS);
337     const Handle(Geom_Surface) bs = gos->BasisSurface();
338     Handle(Geom_Curve) gcbs = bs->UIso(U);
339     GeomAdaptor_Curve gac(gcbs);
340     const GeomAbs_CurveType GACT = gac.GetType();
341     if(IsVP || IsVC || GACT == GeomAbs_BSplineCurve || GACT == GeomAbs_BezierCurve || Abs(LastV - FirstV) < 1.e+5)
342     {
343       Handle(Geom_Curve) gc = gos->UIso(U);
344       if(IsVP && (FirstV == 0.0 && LastV == (2*M_PI))) I = gc;
345       else
346       {
347         Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstV,LastV);
348         //szv:I = Handle(Geom_Curve)::DownCast(gtc);
349         I = gtc;
350       }
351     }
352     else//Offset Line, Parab, Hyperb
353     {
354       Standard_Real VmTr, VMTr;
355       if(GACT != GeomAbs_Hyperbola)
356       {
357         if(FirstV >= 0. && LastV >= 0.){ VmTr = FirstV; VMTr = ((LastV - FirstV) > 1.e+4) ? (FirstV + 1.e+4) : LastV; }
358         else if(FirstV < 0. && LastV < 0.){ VMTr = LastV; VmTr = ((FirstV - LastV) < -1.e+4) ? (LastV - 1.e+4) : FirstV; }
359         else { VmTr = (FirstV < -1.e+4) ? -1.e+4 : FirstV; VMTr = (LastV > 1.e+4) ? 1.e+4 : LastV; }
360       }
361       else//Hyperbola
362       {
363         if(FirstV >= 0. && LastV >= 0.)
364         {
365           if(FirstV > 4.) return;
366           VmTr = FirstV; VMTr = (LastV > 4.) ? 4. : LastV;
367         }
368         else if(FirstV < 0. && LastV < 0.)
369         {
370           if(LastV < -4.) return;
371           VMTr = LastV; VmTr = (FirstV < -4.) ? -4. : FirstV;
372         }
373         else { VmTr = (FirstV < -4.) ? -4. : FirstV; VMTr = (LastV > 4.) ? 4. : LastV; }
374       }
375       //Make trimmed surface
376       Handle(Geom_RectangularTrimmedSurface) rts = new Geom_RectangularTrimmedSurface(gos,VmTr,VMTr,Standard_True);
377       I = rts->UIso(U);
378     }
379   }
380 }
381 //================================================================================
382 //function: FUN_GetViso
383 //================================================================================
384 static void FUN_GetViso(const Handle(Geom_Surface)& GS,
385                         const GeomAbs_SurfaceType&  T,
386                         const Standard_Real&        FirstU,
387                         const Standard_Real&        LastU,
388                         const Standard_Boolean&     IsUC,
389                         const Standard_Boolean&     IsUP,
390                         const Standard_Real&        V,
391                         Handle(Geom_Curve)&         I)
392 {
393   if(T !=  GeomAbs_OffsetSurface)
394   {
395     Handle(Geom_Curve) gc = GS->VIso(V);
396     if(IsUP && (FirstU == 0.0 && LastU == (2*M_PI))) I = gc;
397     else
398     {
399       Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstU,LastU);
400       //szv:I = Handle(Geom_Curve)::DownCast(gtc);
401       I = gtc;
402     }
403   }
404   else//OffsetSurface
405   {
406     const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (GS);
407     const Handle(Geom_Surface) bs = gos->BasisSurface();
408     Handle(Geom_Curve) gcbs = bs->VIso(V);
409     GeomAdaptor_Curve gac(gcbs);
410     const GeomAbs_CurveType GACT = gac.GetType();
411     if(IsUP || IsUC || GACT == GeomAbs_BSplineCurve || GACT == GeomAbs_BezierCurve || Abs(LastU - FirstU) < 1.e+5)
412     {
413       Handle(Geom_Curve) gc = gos->VIso(V);
414       if(IsUP && (FirstU == 0.0 && LastU == (2*M_PI))) I = gc;
415       else
416       {
417         Handle(Geom_TrimmedCurve) gtc = new Geom_TrimmedCurve(gc,FirstU,LastU);
418         //szv:I = Handle(Geom_Curve)::DownCast(gtc);
419         I = gtc;
420       }
421     }
422     else//Offset Line, Parab, Hyperb
423     {
424       Standard_Real UmTr, UMTr;
425       if(GACT != GeomAbs_Hyperbola)
426       {
427         if(FirstU >= 0. && LastU >= 0.){ UmTr = FirstU; UMTr = ((LastU - FirstU) > 1.e+4) ? (FirstU + 1.e+4) : LastU; }
428         else if(FirstU < 0. && LastU < 0.){ UMTr = LastU; UmTr = ((FirstU - LastU) < -1.e+4) ? (LastU - 1.e+4) : FirstU; }
429         else { UmTr = (FirstU < -1.e+4) ? -1.e+4 : FirstU; UMTr = (LastU > 1.e+4) ? 1.e+4 : LastU; }
430       }
431       else//Hyperbola
432       {
433         if(FirstU >= 0. && LastU >= 0.)
434         {
435           if(FirstU > 4.) return;
436           UmTr = FirstU; UMTr = (LastU > 4.) ? 4. : LastU;
437         }
438         else if(FirstU < 0. && LastU < 0.)
439         {
440           if(LastU < -4.) return;
441           UMTr = LastU; UmTr = (FirstU < -4.) ? -4. : FirstU;
442         }
443         else { UmTr = (FirstU < -4.) ? -4. : FirstU; UMTr = (LastU > 4.) ? 4. : LastU; }
444       }
445       //Make trimmed surface
446       Handle(Geom_RectangularTrimmedSurface) rts = new Geom_RectangularTrimmedSurface(gos,UmTr,UMTr,Standard_True);
447       I = rts->VIso(V);
448     }
449   }
450 }
451 //================================================================================
452 //function: FUN_PL_Intersection
453 //================================================================================
454 static void FUN_PL_Intersection(const Handle(Adaptor3d_HSurface)& S1,
455                                 const GeomAbs_SurfaceType&        T1,
456                                 const Handle(Adaptor3d_HSurface)& S2,
457                                 const GeomAbs_SurfaceType&        T2,
458                                 Standard_Boolean&                 IsOk,
459                                 TColgp_SequenceOfPnt&             SP,
460                                 gp_Vec&                           DV)
461 {
462   IsOk = Standard_False;
463   // 1. Check: both surfaces have U(V)isos - lines.
464   DV = gp_Vec(0.,0.,1.);
465   Standard_Boolean isoS1isLine[2] = {0, 0};
466   Standard_Boolean isoS2isLine[2] = {0, 0};
467   Handle(Geom_Curve) C1, C2;
468   const GeomAdaptor_Surface & gas1 = *(GeomAdaptor_Surface*)(&(S1->Surface()));
469   const GeomAdaptor_Surface & gas2 = *(GeomAdaptor_Surface*)(&(S2->Surface()));
470   const Handle(Geom_Surface) gs1 = gas1.Surface();
471   const Handle(Geom_Surface) gs2 = gas2.Surface();
472   Standard_Real MS1[2], MS2[2];
473   MS1[0] = 0.5 * (S1->LastUParameter() + S1->FirstUParameter());
474   MS1[1] = 0.5 * (S1->LastVParameter() + S1->FirstVParameter());
475   MS2[0] = 0.5 * (S2->LastUParameter() + S2->FirstUParameter());
476   MS2[1] = 0.5 * (S2->LastVParameter() + S2->FirstVParameter());
477   if(T1 == GeomAbs_SurfaceOfExtrusion) isoS1isLine[0] = Standard_True;
478   else if(!S1->IsVPeriodic() && !S1->IsVClosed()) {
479     if(T1 != GeomAbs_OffsetSurface) C1 = gs1->UIso(MS1[0]);
480     else {
481       const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs1);
482       const Handle(Geom_Surface) bs = gos->BasisSurface();
483       C1 = bs->UIso(MS1[0]);
484     }
485     GeomAdaptor_Curve gac(C1);
486     if(gac.GetType() == GeomAbs_Line) isoS1isLine[0] = Standard_True;
487   }
488   if(!S1->IsUPeriodic() && !S1->IsUClosed()) {
489     if(T1 != GeomAbs_OffsetSurface) C1 = gs1->VIso(MS1[1]);
490     else {
491       const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs1);
492       const Handle(Geom_Surface) bs = gos->BasisSurface();
493       C1 = bs->VIso(MS1[1]);
494     }
495     GeomAdaptor_Curve gac(C1);
496     if(gac.GetType() == GeomAbs_Line) isoS1isLine[1] = Standard_True;
497   }
498   if(T2 == GeomAbs_SurfaceOfExtrusion) isoS2isLine[0] = Standard_True;
499   else if(!S2->IsVPeriodic() && !S2->IsVClosed()) {
500     if(T2 != GeomAbs_OffsetSurface) C2 = gs2->UIso(MS2[0]);
501     else {
502       const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs2);
503       const Handle(Geom_Surface) bs = gos->BasisSurface();
504       C2 = bs->UIso(MS2[0]);
505     }
506     GeomAdaptor_Curve gac(C2);
507     if(gac.GetType() == GeomAbs_Line) isoS2isLine[0] = Standard_True;
508   }
509   if(!S2->IsUPeriodic() && !S2->IsUClosed()) {
510     if(T2 != GeomAbs_OffsetSurface) C2 = gs2->VIso(MS2[1]);
511     else {
512       const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs2);
513       const Handle(Geom_Surface) bs = gos->BasisSurface();
514       C2 = bs->VIso(MS2[1]);
515     }
516     GeomAdaptor_Curve gac(C2);
517     if(gac.GetType() == GeomAbs_Line) isoS2isLine[1] = Standard_True;
518   }
519   Standard_Boolean IsBothLines = ((isoS1isLine[0] || isoS1isLine[1]) &&
520                                   (isoS2isLine[0] || isoS2isLine[1]));
521   if(!IsBothLines){
522     return;
523   }
524   // 2. Check: Uiso lines of both surfaces are collinear.
525   gp_Pnt puvS1, puvS2;
526   gp_Vec derS1[2], derS2[2];
527   S1->D1(MS1[0], MS1[1], puvS1, derS1[0], derS1[1]);
528   S2->D1(MS2[0], MS2[1], puvS2, derS2[0], derS2[1]);
529   C1.Nullify(); C2.Nullify();
530   Standard_Integer iso = 0;
531   if(isoS1isLine[0] && isoS2isLine[0] &&
532      derS1[1].IsParallel(derS2[1],Precision::Angular())) {
533     iso = 1;
534     FUN_GetViso(gs1,T1,S1->FirstUParameter(),S1->LastUParameter(),
535                 S1->IsUClosed(),S1->IsUPeriodic(),MS1[1],C1);
536     FUN_GetViso(gs2,T2,S2->FirstUParameter(),S2->LastUParameter(),
537                 S2->IsUClosed(),S2->IsUPeriodic(),MS2[1],C2);
538   }
539   else if(isoS1isLine[0] && isoS2isLine[1] &&
540           derS1[1].IsParallel(derS2[0],Precision::Angular())) {
541     iso = 1;
542     FUN_GetViso(gs1,T1,S1->FirstUParameter(),S1->LastUParameter(),
543                 S1->IsUClosed(),S1->IsUPeriodic(),MS1[1],C1);
544     FUN_GetUiso(gs2,T2,S2->FirstVParameter(),S2->LastVParameter(),
545                 S2->IsVClosed(),S2->IsVPeriodic(),MS2[0],C2);
546   }
547   else if(isoS1isLine[1] && isoS2isLine[0] &&
548           derS1[0].IsParallel(derS2[1],Precision::Angular())) {
549     iso = 0;
550     FUN_GetUiso(gs1,T1,S1->FirstVParameter(),S1->LastVParameter(),
551                 S1->IsVClosed(),S1->IsVPeriodic(),MS1[0],C1);
552     FUN_GetViso(gs2,T2,S2->FirstUParameter(),S2->LastUParameter(),
553                 S2->IsUClosed(),S2->IsUPeriodic(),MS2[1],C2);
554   }
555   else if(isoS1isLine[1] && isoS2isLine[1] &&
556           derS1[0].IsParallel(derS2[0],Precision::Angular())) {
557     iso = 0;
558     FUN_GetUiso(gs1,T1,S1->FirstVParameter(),S1->LastVParameter(),
559                 S1->IsVClosed(),S1->IsVPeriodic(),MS1[0],C1);
560     FUN_GetUiso(gs2,T2,S2->FirstVParameter(),S2->LastVParameter(),
561                 S2->IsVClosed(),S2->IsVPeriodic(),MS2[0],C2);
562   }
563   else {
564     IsOk = Standard_False;
565     return;
566   }
567   IsOk = Standard_True;
568   // 3. Make intersections of V(U)isos
569   if(C1.IsNull() || C2.IsNull()) return;
570   DV = derS1[iso];
571   Handle(Geom_Plane) GPln = new Geom_Plane(gp_Pln(puvS1,gp_Dir(DV)));
572   Handle(Geom_Curve) C1Prj =
573     GeomProjLib::ProjectOnPlane(C1,GPln,gp_Dir(DV),Standard_True);
574   Handle(Geom_Curve) C2Prj =
575     GeomProjLib::ProjectOnPlane(C2,GPln,gp_Dir(DV),Standard_True);
576   if(C1Prj.IsNull() || C2Prj.IsNull()) return;
577   Handle(Geom2d_Curve) C1Prj2d = GeomProjLib::Curve2d (C1Prj,GPln);
578   Handle(Geom2d_Curve) C2Prj2d = GeomProjLib::Curve2d (C2Prj,GPln);
579   Geom2dAPI_InterCurveCurve ICC(C1Prj2d,C2Prj2d,1.0e-7);
580   if(ICC.NbPoints() > 0 )
581   {
582     for(Standard_Integer ip = 1; ip <= ICC.NbPoints(); ip++)
583     {
584       gp_Pnt2d P = ICC.Point(ip);
585       gp_Pnt P3d = ElCLib::To3d(gp_Ax2(puvS1,gp_Dir(DV)),P);
586       SP.Append(P3d);
587     }
588   }
589 }
590 //================================================================================
591 //function: FUN_NewFirstLast
592 //================================================================================
593 static void FUN_NewFirstLast(const GeomAbs_CurveType& ga_ct,
594                              const Standard_Real&     Fst,
595                              const Standard_Real&     Lst,
596                              const Standard_Real&     TrVal,
597                              Standard_Real&           NewFst,
598                              Standard_Real&           NewLst,
599                              Standard_Boolean&        NeedTr)
600 {
601   NewFst = Fst; NewLst = Lst; NeedTr = Standard_False;
602   switch (ga_ct)
603   {
604     case GeomAbs_Line:
605     case GeomAbs_Parabola:
606     {
607       if(Abs(Lst - Fst) > TrVal)
608       {
609         if(Fst >= 0. && Lst >= 0.)
610         {
611           NewFst = Fst;
612           NewLst = ((Fst + TrVal) < Lst) ? (Fst + TrVal) : Lst;
613         }
614         if(Fst < 0. && Lst < 0.)
615         {
616           NewLst = Lst;
617           NewFst = ((Lst - TrVal) > Fst) ? (Lst - TrVal) : Fst;
618         }
619         else
620         {
621           NewFst = (Fst < -TrVal) ? -TrVal : Fst;
622           NewLst = (Lst > TrVal) ? TrVal : Lst;
623         }
624         NeedTr = Standard_True;
625       }
626       break;
627     }
628     case GeomAbs_Hyperbola:
629     {
630       if(Abs(Lst - Fst) > 10.)
631       { 
632         if(Fst >= 0. && Lst >= 0.)
633         {
634           if(Fst > 4.) return;
635           NewFst = Fst;
636           NewLst = (Lst > 4.) ? 4. : Lst;
637         }
638         if(Fst < 0. && Lst < 0.)
639         {
640           if(Lst < -4.) return;
641           NewLst = Lst;
642           NewFst = (Fst < -4.) ? -4. : Fst;
643         }
644         else
645         {
646           NewFst = (Fst < -4.) ? -4. : Fst;
647           NewLst = (Lst > 4.) ? 4. : Lst;
648         }
649         NeedTr = Standard_True;
650       }
651       break;
652     }
653     default:
654     break;
655   }
656 }
657 //================================================================================
658 //function: FUN_TrimBothSurf
659 //================================================================================
660 static void FUN_TrimBothSurf(const Handle(Adaptor3d_HSurface)& S1,
661                              const GeomAbs_SurfaceType&        T1,
662                              const Handle(Adaptor3d_HSurface)& S2,
663                              const GeomAbs_SurfaceType&        T2,
664                              const Standard_Real&              TV,
665                              Handle(Adaptor3d_HSurface)&       NS1,
666                              Handle(Adaptor3d_HSurface)&       NS2)
667 {
668   const GeomAdaptor_Surface & gas1 = *(GeomAdaptor_Surface*)(&(S1->Surface()));
669   const GeomAdaptor_Surface & gas2 = *(GeomAdaptor_Surface*)(&(S2->Surface()));
670   const Handle(Geom_Surface) gs1 = gas1.Surface();
671   const Handle(Geom_Surface) gs2 = gas2.Surface();
672   const Standard_Real UM1 = 0.5 * (S1->LastUParameter() + S1->FirstUParameter());
673   const Standard_Real UM2 = 0.5 * (S2->LastUParameter() + S2->FirstUParameter());
674   const Standard_Real VM1 = 0.5 * (S1->LastVParameter() + S1->FirstVParameter());
675   const Standard_Real VM2 = 0.5 * (S2->LastVParameter() + S2->FirstVParameter());
676   Handle(Geom_Curve) visoS1, visoS2, uisoS1, uisoS2;
677   if(T1 != GeomAbs_OffsetSurface){ visoS1 = gs1->VIso(VM1); uisoS1 = gs1->UIso(UM1); }
678   else
679   {
680     const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs1);
681     const Handle(Geom_Surface) bs = gos->BasisSurface();
682     visoS1 = bs->VIso(VM1); uisoS1 = bs->UIso(UM1);
683   }
684   if(T2 != GeomAbs_OffsetSurface){ visoS2 = gs2->VIso(VM2); uisoS2 = gs2->UIso(UM2); }
685   else
686   {
687     const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs2);
688     const Handle(Geom_Surface) bs = gos->BasisSurface();
689     visoS2 = bs->VIso(VM2); uisoS2 = bs->UIso(UM2);
690   }
691   if(uisoS1.IsNull() || uisoS2.IsNull() || visoS1.IsNull() || visoS2.IsNull()){ NS1 = S1; NS2 = S2; return; }
692   GeomAdaptor_Curve gau1(uisoS1);
693   GeomAdaptor_Curve gav1(visoS1);
694   GeomAdaptor_Curve gau2(uisoS2);
695   GeomAdaptor_Curve gav2(visoS2);
696   GeomAbs_CurveType GA_U1 = gau1.GetType();
697   GeomAbs_CurveType GA_V1 = gav1.GetType();
698   GeomAbs_CurveType GA_U2 = gau2.GetType();
699   GeomAbs_CurveType GA_V2 = gav2.GetType();
700   Standard_Boolean TrmU1 = Standard_False;
701   Standard_Boolean TrmV1 = Standard_False;
702   Standard_Boolean TrmU2 = Standard_False;
703   Standard_Boolean TrmV2 = Standard_False;
704   Standard_Real V1S1,V2S1,U1S1,U2S1, V1S2,V2S2,U1S2,U2S2;
705   FUN_NewFirstLast(GA_U1,S1->FirstVParameter(),S1->LastVParameter(),TV,V1S1,V2S1,TrmV1);
706   FUN_NewFirstLast(GA_V1,S1->FirstUParameter(),S1->LastUParameter(),TV,U1S1,U2S1,TrmU1);
707   FUN_NewFirstLast(GA_U2,S2->FirstVParameter(),S2->LastVParameter(),TV,V1S2,V2S2,TrmV2);
708   FUN_NewFirstLast(GA_V2,S2->FirstUParameter(),S2->LastUParameter(),TV,U1S2,U2S2,TrmU2);
709   if(TrmV1) NS1 = S1->VTrim(V1S1, V2S1, 1.0e-7);
710   if(TrmV2) NS2 = S2->VTrim(V1S2, V2S2, 1.0e-7);
711   if(TrmU1)
712   {
713     if(TrmV1)
714     {
715       Handle(Adaptor3d_HSurface) TS = NS1;
716       NS1 = TS->UTrim(U1S1, U2S1, 1.0e-7);
717     }
718     else NS1 = S1->UTrim(U1S1, U2S1, 1.0e-7);
719   }
720   if(TrmU2)
721   {
722     if(TrmV2)
723     {
724       Handle(Adaptor3d_HSurface) TS = NS2;
725       NS2 = TS->UTrim(U1S2, U2S2, 1.0e-7);
726     }
727     else NS2 = S2->UTrim(U1S2, U2S2, 1.0e-7);
728   }
729 }
730
731 //=======================================================================
732 //function : Perform
733 //purpose  : 
734 //=======================================================================
735 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
736                                     const Handle(Adaptor3d_TopolTool)& theD1,
737                                     const Handle(Adaptor3d_HSurface)&  theS2,
738                                     const Handle(Adaptor3d_TopolTool)& theD2,
739                                     const Standard_Real TolArc,
740                                     const Standard_Real TolTang,
741                                     const Standard_Boolean isGeomInt,
742                                     const Standard_Boolean theIsReqToKeepRLine,
743                                     const Standard_Boolean theIsReqToPostWLProc)
744 {
745   myTolArc = TolArc;
746   myTolTang = TolTang;
747   if(myFleche <= Precision::PConfusion())
748     myFleche = 0.01;
749   if(myUVMaxStep <= Precision::PConfusion())
750     myUVMaxStep = 0.01;
751
752   done = Standard_False;
753   spnt.Clear();
754   slin.Clear();
755   empt = Standard_True;
756   tgte = Standard_False;
757   oppo = Standard_False;
758
759   GeomAbs_SurfaceType typs1 = theS1->GetType();
760   GeomAbs_SurfaceType typs2 = theS2->GetType();
761   
762   //treatment of the cases with cone or torus
763   Standard_Boolean TreatAsBiParametric = Standard_False;
764   Standard_Integer bGeomGeom = 0;
765   //
766   if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone ||
767       typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
768     gp_Ax1 aCTAx, aGeomAx;
769     GeomAbs_SurfaceType aCTType;
770     Standard_Boolean bToCheck;
771     //
772     const Handle(Adaptor3d_HSurface)& aCTSurf = 
773       (typs1 == GeomAbs_Cone || typs1 == GeomAbs_Torus) ? theS1 : theS2;
774     const Handle(Adaptor3d_HSurface)& aGeomSurf = 
775       (typs1 == GeomAbs_Cone || typs1 == GeomAbs_Torus) ? theS2 : theS1;
776     //
777     aCTType = aCTSurf->GetType();
778     bToCheck = Standard_False;
779     //
780     if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone) {
781       const gp_Cone aCon1 = (aCTType == GeomAbs_Cone) ? 
782         aCTSurf->Cone() : aGeomSurf->Cone();
783       Standard_Real a1 = Abs(aCon1.SemiAngle());
784       bToCheck = (a1 < 0.02) || (a1 > 1.55);
785       //
786       if (typs1 == typs2) {
787         const gp_Cone aCon2 = aGeomSurf->Cone();
788         Standard_Real a2 = Abs(aCon2.SemiAngle());
789         bToCheck = bToCheck || (a2 < 0.02) || (a2 > 1.55);
790         //
791         if (a1 > 1.55 && a2 > 1.55) {//quasi-planes: if same domain, treat as canonic
792           const gp_Ax1 A1 = aCon1.Axis(), A2 = aCon2.Axis();
793           if (A1.IsParallel(A2,Precision::Angular())) {
794             const gp_Pnt Apex1 = aCon1.Apex(), Apex2 = aCon2.Apex();
795             const gp_Pln Plan1( Apex1, A1.Direction() );
796             if (Plan1.Distance( Apex2 ) <= Precision::Confusion()) {
797               bToCheck = Standard_False;
798             }
799           }
800         }
801       }
802       //
803       TreatAsBiParametric = bToCheck;
804       if (aCTType == GeomAbs_Cone) {
805         aCTAx = aCon1.Axis();
806       }
807     }
808     //
809     if (typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
810       const gp_Torus aTor1 = (aCTType == GeomAbs_Torus) ? 
811         aCTSurf->Torus() : aGeomSurf->Torus();
812       bToCheck = aTor1.MajorRadius() > aTor1.MinorRadius();
813       if (typs1 == typs2) {
814         const gp_Torus aTor2 = aGeomSurf->Torus();
815         bToCheck = aTor2.MajorRadius() > aTor2.MinorRadius();
816       }
817       //
818       if (aCTType == GeomAbs_Torus) {
819         aCTAx = aTor1.Axis();
820       }
821     }
822     //
823     if (bToCheck) {
824       const gp_Lin aL1(aCTAx);
825       //
826       switch (aGeomSurf->GetType()) {
827       case GeomAbs_Plane: {
828         aGeomAx = aGeomSurf->Plane().Axis();
829         if (aCTType == GeomAbs_Cone) {
830           bGeomGeom = 1;
831           if (Abs(aCTSurf->Cone().SemiAngle()) < 0.02) {
832             Standard_Real ps = Abs(aCTAx.Direction().Dot(aGeomAx.Direction()));
833             if(ps < 0.015) {
834               bGeomGeom = 0;
835             }
836           }
837         }
838         else {
839           if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) ||
840               (aCTAx.IsNormal(aGeomAx, Precision::Angular()) && 
841                (aGeomSurf->Plane().Distance(aCTAx.Location()) < Precision::Confusion()))) {
842             bGeomGeom = 1;
843           }
844         }
845         bToCheck = Standard_False;
846         break;
847       }
848       case GeomAbs_Sphere: {
849         if (aL1.Distance(aGeomSurf->Sphere().Location()) < Precision::Confusion()) {
850           bGeomGeom = 1;
851         }
852         bToCheck = Standard_False;
853         break;
854       }
855       case GeomAbs_Cylinder:
856         aGeomAx = aGeomSurf->Cylinder().Axis();
857         break;
858       case GeomAbs_Cone: 
859         aGeomAx = aGeomSurf->Cone().Axis();
860         break;
861       case GeomAbs_Torus: 
862         aGeomAx = aGeomSurf->Torus().Axis();
863         break;
864       default: 
865         bToCheck = Standard_False;
866         break;
867       }
868       //
869       if (bToCheck) {
870         if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) &&
871             (aL1.Distance(aGeomAx.Location()) <= Precision::Confusion())) {
872           bGeomGeom = 1;
873         }
874       }
875       //
876       if (bGeomGeom == 1) {
877         TreatAsBiParametric = Standard_False;
878       }
879     }
880   }
881   //
882
883   if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite()) {
884     TreatAsBiParametric= Standard_False;
885   }
886
887 //  Modified by skv - Mon Sep 26 14:58:30 2005 Begin
888 //   if(TreatAsBiParametric) { typs1 = typs2 = GeomAbs_BezierSurface; }
889   if(TreatAsBiParametric)
890   {
891     if (typs1 == GeomAbs_Cone && typs2 == GeomAbs_Plane)
892       typs1 = GeomAbs_BezierSurface; // Using Imp-Prm Intersector
893     else if (typs1 == GeomAbs_Plane && typs2 == GeomAbs_Cone)
894       typs2 = GeomAbs_BezierSurface; // Using Imp-Prm Intersector
895     else {
896       // Using Prm-Prm Intersector
897       typs1 = GeomAbs_BezierSurface;
898       typs2 = GeomAbs_BezierSurface;
899     }
900   }
901 //  Modified by skv - Mon Sep 26 14:58:30 2005 End
902
903   // Surface type definition
904   Standard_Integer ts1 = 0;
905   switch (typs1)
906   {
907     case GeomAbs_Plane:
908     case GeomAbs_Cylinder:
909     case GeomAbs_Sphere:
910     case GeomAbs_Cone: ts1 = 1; break;
911     case GeomAbs_Torus: ts1 = bGeomGeom; break;
912     default: break;
913   }
914
915   Standard_Integer ts2 = 0;
916   switch (typs2)
917   {
918     case GeomAbs_Plane:
919     case GeomAbs_Cylinder:
920     case GeomAbs_Sphere:
921     case GeomAbs_Cone: ts2 = 1; break;
922     case GeomAbs_Torus: ts2 = bGeomGeom; break;
923     default: break;
924   }
925   //
926   // treatment of the cases with torus and any other geom surface
927   //
928   // Possible intersection types: 1. ts1 == ts2 == 1 <Geom-Geom>
929   //                              2. ts1 != ts2      <Geom-Param>
930   //                              3. ts1 == ts2 == 0 <Param-Param>
931
932   // Geom - Geom
933   const Standard_Boolean RestrictLine = Standard_True;
934   if(ts1 == ts2 && ts1 == 1)
935   {
936     IntSurf_ListOfPntOn2S ListOfPnts;
937     ListOfPnts.Clear();
938     if(isGeomInt)
939     {
940       GeomGeomPerfom( theS1, theD1, theS2, theD2, TolArc, 
941                       TolTang, ListOfPnts, RestrictLine,
942                       typs1, typs2, theIsReqToKeepRLine);
943     }
944     else
945     {
946       ParamParamPerfom(theS1, theD1, theS2, theD2, 
947               TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
948     }
949   }
950
951   // Geom - Param
952   if(ts1 != ts2)
953   {
954     GeomParamPerfom(theS1, theD1, theS2, theD2, ts1 == 0, typs1, typs2);
955   }
956
957   // Param - Param 
958   if(ts1 == ts2 && ts1 == 0)
959   {
960     IntSurf_ListOfPntOn2S ListOfPnts;
961     ListOfPnts.Clear();
962
963     ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
964                         TolTang, ListOfPnts, RestrictLine, typs1, typs2);
965   }
966
967   if(!theIsReqToPostWLProc)
968     return;
969
970   for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
971   {
972     Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
973
974     if(aWL.IsNull())
975       continue;
976
977     if (!aWL->IsPurgingAllowed())
978       continue;
979
980     Handle(IntPatch_WLine) aRW =
981       IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
982
983     if(aRW.IsNull())
984       continue;
985
986     slin.InsertAfter(i, aRW);
987     slin.Remove(i);
988   }
989 }
990
991 //=======================================================================
992 //function : Perform
993 //purpose  : 
994 //=======================================================================
995 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
996                                     const Handle(Adaptor3d_TopolTool)& theD1,
997                                     const Handle(Adaptor3d_HSurface)&  theS2,
998                                     const Handle(Adaptor3d_TopolTool)& theD2,
999                                     const Standard_Real TolArc,
1000                                     const Standard_Real TolTang,
1001                                     IntSurf_ListOfPntOn2S& ListOfPnts,
1002                                     const Standard_Boolean RestrictLine,
1003                                     const Standard_Boolean isGeomInt,
1004                                     const Standard_Boolean theIsReqToKeepRLine,
1005                                     const Standard_Boolean theIsReqToPostWLProc)
1006 {
1007   myTolArc = TolArc;
1008   myTolTang = TolTang;
1009   if(myFleche <= Precision::PConfusion())
1010     myFleche = 0.01;
1011   if(myUVMaxStep <= Precision::PConfusion())
1012     myUVMaxStep = 0.01;
1013     
1014   done = Standard_False;
1015   spnt.Clear();
1016   slin.Clear();
1017   empt = Standard_True;
1018   tgte = Standard_False;
1019   oppo = Standard_False;
1020
1021   GeomAbs_SurfaceType typs1 = theS1->GetType();
1022   GeomAbs_SurfaceType typs2 = theS2->GetType();
1023   //
1024   //treatment of the cases with cone or torus
1025   Standard_Boolean TreatAsBiParametric = Standard_False;
1026   Standard_Integer bGeomGeom = 0;
1027   //
1028   if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone ||
1029       typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
1030     gp_Ax1 aCTAx, aGeomAx;
1031     GeomAbs_SurfaceType aCTType;
1032     Standard_Boolean bToCheck;
1033     //
1034     const Handle(Adaptor3d_HSurface)& aCTSurf = 
1035       (typs1 == GeomAbs_Cone || typs1 == GeomAbs_Torus) ? theS1 : theS2;
1036     const Handle(Adaptor3d_HSurface)& aGeomSurf = 
1037       (typs1 == GeomAbs_Cone || typs1 == GeomAbs_Torus) ? theS2 : theS1;
1038     //
1039     aCTType = aCTSurf->GetType();
1040     bToCheck = Standard_False;
1041     //
1042     if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone) {
1043       const gp_Cone aCon1 = (aCTType == GeomAbs_Cone) ? 
1044         aCTSurf->Cone() : aGeomSurf->Cone();
1045       Standard_Real a1 = Abs(aCon1.SemiAngle());
1046       bToCheck = (a1 < 0.02) || (a1 > 1.55);
1047       //
1048       if (typs1 == typs2) {
1049         const gp_Cone aCon2 = aGeomSurf->Cone();
1050         Standard_Real a2 = Abs(aCon2.SemiAngle());
1051         bToCheck = bToCheck || (a2 < 0.02) || (a2 > 1.55);
1052         //
1053         if (a1 > 1.55 && a2 > 1.55) {//quasi-planes: if same domain, treat as canonic
1054           const gp_Ax1 A1 = aCon1.Axis(), A2 = aCon2.Axis();
1055           if (A1.IsParallel(A2,Precision::Angular())) {
1056             const gp_Pnt Apex1 = aCon1.Apex(), Apex2 = aCon2.Apex();
1057             const gp_Pln Plan1( Apex1, A1.Direction() );
1058             if (Plan1.Distance( Apex2 ) <= Precision::Confusion()) {
1059               bToCheck = Standard_False;
1060             }
1061           }
1062         }
1063       }
1064       //
1065       TreatAsBiParametric = bToCheck;
1066       if (aCTType == GeomAbs_Cone) {
1067         aCTAx = aCon1.Axis();
1068       }
1069     }
1070     //
1071     if (typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
1072       const gp_Torus aTor1 = (aCTType == GeomAbs_Torus) ? 
1073         aCTSurf->Torus() : aGeomSurf->Torus();
1074       bToCheck = aTor1.MajorRadius() > aTor1.MinorRadius();
1075       if (typs1 == typs2) {
1076         const gp_Torus aTor2 = aGeomSurf->Torus();
1077         bToCheck = aTor2.MajorRadius() > aTor2.MinorRadius();
1078       }
1079       //
1080       if (aCTType == GeomAbs_Torus) {
1081         aCTAx = aTor1.Axis();
1082       }
1083     }
1084     //
1085     if (bToCheck) {
1086       const gp_Lin aL1(aCTAx);
1087       //
1088       switch (aGeomSurf->GetType()) {
1089       case GeomAbs_Plane: {
1090         aGeomAx = aGeomSurf->Plane().Axis();
1091         if (aCTType == GeomAbs_Cone) {
1092           bGeomGeom = 1;
1093           if (Abs(aCTSurf->Cone().SemiAngle()) < 0.02) {
1094             Standard_Real ps = Abs(aCTAx.Direction().Dot(aGeomAx.Direction()));
1095             if(ps < 0.015) {
1096               bGeomGeom = 0;
1097             }
1098           }
1099         }
1100         else {
1101           if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) ||
1102               (aCTAx.IsNormal(aGeomAx, Precision::Angular()) && 
1103                (aGeomSurf->Plane().Distance(aCTAx.Location()) < Precision::Confusion()))) {
1104             bGeomGeom = 1;
1105           }
1106         }
1107         bToCheck = Standard_False;
1108         break;
1109       }
1110       case GeomAbs_Sphere: {
1111         if (aL1.Distance(aGeomSurf->Sphere().Location()) < Precision::Confusion()) {
1112           bGeomGeom = 1;
1113         }
1114         bToCheck = Standard_False;
1115         break;
1116       }
1117       case GeomAbs_Cylinder:
1118         aGeomAx = aGeomSurf->Cylinder().Axis();
1119         break;
1120       case GeomAbs_Cone: 
1121         aGeomAx = aGeomSurf->Cone().Axis();
1122         break;
1123       case GeomAbs_Torus: 
1124         aGeomAx = aGeomSurf->Torus().Axis();
1125         break;
1126       default: 
1127         bToCheck = Standard_False;
1128         break;
1129       }
1130       //
1131       if (bToCheck) {
1132         if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) &&
1133             (aL1.Distance(aGeomAx.Location()) <= Precision::Confusion())) {
1134           bGeomGeom = 1;
1135         }
1136       }
1137       //
1138       if (bGeomGeom == 1) {
1139         TreatAsBiParametric = Standard_False;
1140       }
1141     }
1142   }
1143   //
1144
1145   if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite()) {
1146     TreatAsBiParametric= Standard_False;
1147   }
1148
1149   if(TreatAsBiParametric)
1150   {
1151     // Using Prm-Prm Intersector
1152     typs1 = GeomAbs_BezierSurface;
1153     typs2 = GeomAbs_BezierSurface;
1154   }
1155
1156   // Surface type definition
1157   Standard_Integer ts1 = 0;
1158   switch (typs1)
1159   {
1160     case GeomAbs_Plane:
1161     case GeomAbs_Cylinder:
1162     case GeomAbs_Sphere:
1163     case GeomAbs_Cone: ts1 = 1; break;
1164     case GeomAbs_Torus: ts1 = bGeomGeom; break;
1165     default: break;
1166   }
1167
1168   Standard_Integer ts2 = 0;
1169   switch (typs2)
1170   {
1171     case GeomAbs_Plane:
1172     case GeomAbs_Cylinder:
1173     case GeomAbs_Sphere:
1174     case GeomAbs_Cone: ts2 = 1; break;
1175     case GeomAbs_Torus: ts2 = bGeomGeom; break;
1176     default: break;
1177   }
1178   //
1179   // Possible intersection types: 1. ts1 == ts2 == 1 <Geom-Geom>
1180   //                              2. ts1 != ts2      <Geom-Param>
1181   //                              3. ts1 == ts2 == 0 <Param-Param>
1182
1183   if(!isGeomInt)
1184   {
1185     ParamParamPerfom(theS1, theD1, theS2, theD2, 
1186                 TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
1187   }
1188   else if(ts1 != ts2)
1189   {
1190     GeomParamPerfom(theS1, theD1, theS2, theD2, ts1 == 0, typs1, typs2);
1191   }
1192   else if (ts1 == 0)
1193   {
1194     ParamParamPerfom(theS1, theD1, theS2, theD2,
1195                 TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
1196   }
1197   else if(ts1 == 1)
1198   {
1199     GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, 
1200                     TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
1201   }
1202
1203   if(!theIsReqToPostWLProc)
1204     return;
1205
1206   for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
1207   {
1208     Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
1209
1210     if(aWL.IsNull())
1211       continue;
1212
1213     if(!aWL->IsPurgingAllowed())
1214       continue;
1215
1216     Handle(IntPatch_WLine) aRW = 
1217       IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2, RestrictLine);
1218
1219     if(aRW.IsNull())
1220       continue;
1221
1222     slin.InsertAfter(i, aRW);
1223     slin.Remove(i);
1224   }
1225 }
1226
1227 //=======================================================================
1228 //function : ParamParamPerfom
1229 //purpose  : 
1230 //=======================================================================
1231 void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
1232                                              const Handle(Adaptor3d_TopolTool)& theD1,
1233                                              const Handle(Adaptor3d_HSurface)&  theS2,
1234                                              const Handle(Adaptor3d_TopolTool)& theD2,
1235                                              const Standard_Real TolArc,
1236                                              const Standard_Real TolTang,
1237                                              IntSurf_ListOfPntOn2S& ListOfPnts,
1238                                              const Standard_Boolean RestrictLine,
1239                                              const GeomAbs_SurfaceType typs1,
1240                                              const GeomAbs_SurfaceType typs2)
1241 {
1242   IntPatch_PrmPrmIntersection interpp;
1243   if(!theD1->DomainIsInfinite() && !theD2->DomainIsInfinite())
1244   {
1245     Standard_Boolean ClearFlag = Standard_True;
1246     if(!ListOfPnts.IsEmpty())
1247     {
1248       interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
1249       ClearFlag = Standard_False;
1250     }
1251     interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag);   //double call!!!!!!!
1252   }
1253   else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
1254   {
1255     gp_Pnt pMaxXYZ, pMinXYZ;
1256     if(theD1->DomainIsInfinite())
1257     {
1258       FUN_GetMinMaxXYZPnt( theS2, pMinXYZ, pMaxXYZ );
1259       const Standard_Real MU = Max(Abs(theS2->FirstUParameter()),Abs(theS2->LastUParameter()));
1260       const Standard_Real MV = Max(Abs(theS2->FirstVParameter()),Abs(theS2->LastVParameter()));
1261       const Standard_Real AP = Max(MU, MV);
1262       Handle(Adaptor3d_HSurface) SS;
1263       FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS1, AP, SS);
1264       interpp.Perform(SS,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
1265     }
1266     else
1267     {
1268       FUN_GetMinMaxXYZPnt( theS1, pMinXYZ, pMaxXYZ );
1269       const Standard_Real MU = Max(Abs(theS1->FirstUParameter()),Abs(theS1->LastUParameter()));
1270       const Standard_Real MV = Max(Abs(theS1->FirstVParameter()),Abs(theS1->LastVParameter()));
1271       const Standard_Real AP = Max(MU, MV);
1272       Handle(Adaptor3d_HSurface) SS;
1273       FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS2, AP, SS);
1274       interpp.Perform(theS1, theD1, SS, theD2,TolTang, TolArc,myFleche,myUVMaxStep);
1275     }
1276   }//(theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite())
1277   else
1278   {
1279     if(typs1 == GeomAbs_OtherSurface || typs2 == GeomAbs_OtherSurface)
1280     {
1281       done = Standard_False;
1282       return;
1283     }
1284
1285     Standard_Boolean IsPLInt = Standard_False;
1286     TColgp_SequenceOfPnt sop;
1287     gp_Vec v;
1288     FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v);
1289
1290     if(IsPLInt)
1291     {
1292       if(sop.Length() > 0)
1293       {
1294         for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
1295         {
1296           gp_Lin lin(sop.Value(ip),gp_Dir(v));
1297           Handle(IntPatch_Line) gl = new IntPatch_GLine(lin,Standard_False);
1298           slin.Append(gl);
1299         }
1300
1301         done = Standard_True;
1302       }
1303       else
1304         done = Standard_False;
1305
1306       return;
1307     }// 'COLLINEAR LINES'
1308     else
1309     {
1310       Handle(Adaptor3d_HSurface) nS1 = theS1;
1311       Handle(Adaptor3d_HSurface) nS2 = theS2;
1312       FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+8,nS1,nS2);
1313       interpp.Perform(nS1,theD1,nS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
1314     }// 'NON - COLLINEAR LINES'
1315   }// both domains are infinite
1316
1317   if (interpp.IsDone())
1318   {
1319     done = Standard_True;
1320     tgte = Standard_False;
1321     empt = interpp.IsEmpty();
1322
1323     for(Standard_Integer i = 1; i <= interpp.NbLines(); i++)
1324     {
1325       if(interpp.Line(i)->ArcType() != IntPatch_Walking)
1326         slin.Append(interpp.Line(i));
1327     }
1328
1329     for (Standard_Integer i = 1; i <= interpp.NbLines(); i++)
1330     {
1331       if(interpp.Line(i)->ArcType() == IntPatch_Walking)
1332         slin.Append(interpp.Line(i));
1333     }
1334   }
1335 }
1336
1337 //=======================================================================
1338 ////function : GeomGeomPerfom
1339 //purpose  : 
1340 //=======================================================================
1341 void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& theS1,
1342                                            const Handle(Adaptor3d_TopolTool)& theD1,
1343                                            const Handle(Adaptor3d_HSurface)& theS2,
1344                                            const Handle(Adaptor3d_TopolTool)& theD2,
1345                                            const Standard_Real TolArc,
1346                                            const Standard_Real TolTang,
1347                                            IntSurf_ListOfPntOn2S& ListOfPnts,
1348                                            const Standard_Boolean RestrictLine,
1349                                            const GeomAbs_SurfaceType theTyps1,
1350                                            const GeomAbs_SurfaceType theTyps2,
1351                                            const Standard_Boolean theIsReqToKeepRLine)
1352 {
1353   IntPatch_ImpImpIntersection interii(theS1,theD1,theS2,theD2,
1354                                       myTolArc,myTolTang, theIsReqToKeepRLine);
1355
1356   if (!interii.IsDone())
1357   {
1358     done = Standard_False;
1359     ParamParamPerfom(theS1, theD1, theS2, theD2, 
1360                 TolArc, TolTang, ListOfPnts, RestrictLine, theTyps1, theTyps2);
1361     return;
1362   }
1363
1364   done = (interii.GetStatus() == IntPatch_ImpImpIntersection::IntStatus_OK);
1365   empt = interii.IsEmpty();
1366
1367   if(empt)
1368   {
1369     return;
1370   }
1371
1372   const Standard_Integer aNbPointsInALine = 200;
1373
1374   tgte = interii.TangentFaces();
1375   if (tgte)
1376     oppo = interii.OppositeFaces();
1377
1378   Standard_Boolean isWLExist = Standard_False;
1379   IntPatch_ALineToWLine AToW(theS1, theS2, aNbPointsInALine);
1380
1381   for (Standard_Integer i = 1; i <= interii.NbLines(); i++)
1382   {
1383     const Handle(IntPatch_Line)& line = interii.Line(i);
1384     if (line->ArcType() == IntPatch_Analytic)
1385     {
1386       isWLExist = Standard_True;
1387       AToW.MakeWLine(Handle(IntPatch_ALine)::DownCast(line), slin);
1388     }
1389     else
1390     {
1391       if (line->ArcType() == IntPatch_Walking)
1392       {
1393         Handle(IntPatch_WLine)::DownCast(line)->EnablePurging(Standard_False);
1394       }
1395
1396       if((line->ArcType() != IntPatch_Restriction) || theIsReqToKeepRLine)
1397         slin.Append(line);
1398     }
1399   }
1400
1401   for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)
1402   {
1403     spnt.Append(interii.Point(i));
1404   }
1405
1406   if((theTyps1 == GeomAbs_Cylinder) && (theTyps2 == GeomAbs_Cylinder))
1407   {
1408     IntPatch_WLineTool::JoinWLines(slin, spnt, theS1, theS2, TolTang);
1409   }
1410
1411   if(isWLExist)
1412   {
1413     Bnd_Box2d aBx1, aBx2;
1414     const Standard_Real aU1F = theS1->FirstUParameter(),
1415                         aU1L = theS1->LastUParameter(),
1416                         aV1F = theS1->FirstVParameter(),
1417                         aV1L = theS1->LastVParameter(),
1418                         aU2F = theS2->FirstUParameter(),
1419                         aU2L = theS2->LastUParameter(),
1420                         aV2F = theS2->FirstVParameter(),
1421                         aV2L = theS2->LastVParameter();
1422     aBx1.Add(gp_Pnt2d(aU1F, aV1F));
1423     aBx1.Add(gp_Pnt2d(aU1L, aV1F));
1424     aBx1.Add(gp_Pnt2d(aU1L, aV1L));
1425     aBx1.Add(gp_Pnt2d(aU1F, aV1L));
1426     aBx2.Add(gp_Pnt2d(aU2F, aV2F));
1427     aBx2.Add(gp_Pnt2d(aU2L, aV2F));
1428     aBx2.Add(gp_Pnt2d(aU2L, aV2L));
1429     aBx2.Add(gp_Pnt2d(aU2F, aV2L));
1430
1431     aBx1.Enlarge(Precision::PConfusion());
1432     aBx2.Enlarge(Precision::PConfusion());
1433
1434     const Standard_Real
1435             anArrOfPeriod[4] = {theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
1436                                 theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
1437                                 theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
1438                                 theS2->IsVPeriodic()? theS2->VPeriod() : 0.0};
1439     IntPatch_WLineTool::ExtendTwoWLines(slin, theS1, theS2, TolTang,
1440                                         anArrOfPeriod, aBx1, aBx2);
1441   }
1442 }
1443
1444 //=======================================================================
1445 //function : GeomParamPerfom
1446 //purpose  : 
1447 //=======================================================================
1448 void IntPatch_Intersection::
1449   GeomParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
1450                   const Handle(Adaptor3d_TopolTool)& theD1,
1451                   const Handle(Adaptor3d_HSurface)&  theS2,
1452                   const Handle(Adaptor3d_TopolTool)& theD2,
1453                   const Standard_Boolean isNotAnalitical,
1454                   const GeomAbs_SurfaceType typs1,
1455                   const GeomAbs_SurfaceType typs2)
1456 {
1457   IntPatch_ImpPrmIntersection interip;
1458   if (myIsStartPnt)
1459   {
1460     if (isNotAnalitical/*ts1 == 0*/)
1461       interip.SetStartPoint(myU1Start,myV1Start);
1462     else
1463       interip.SetStartPoint(myU2Start,myV2Start);
1464   }
1465
1466   if(theD1->DomainIsInfinite() && theD2->DomainIsInfinite())
1467   {
1468     Standard_Boolean IsPLInt = Standard_False;
1469     TColgp_SequenceOfPnt sop;
1470     gp_Vec v;
1471     FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v);
1472     
1473     if(IsPLInt)
1474     {
1475       if(sop.Length() > 0)
1476       {
1477         for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
1478         {
1479           gp_Lin lin(sop.Value(ip),gp_Dir(v));
1480           Handle(IntPatch_Line) gl = new IntPatch_GLine(lin,Standard_False);
1481           slin.Append(gl);
1482         }
1483
1484         done = Standard_True;
1485       }
1486       else
1487         done = Standard_False;
1488
1489       return;
1490     }
1491     else
1492     {
1493       Handle(Adaptor3d_HSurface) nS1 = theS1;
1494       Handle(Adaptor3d_HSurface) nS2 = theS2;
1495       FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+5,nS1,nS2);
1496       interip.Perform(nS1,theD1,nS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep);
1497     }
1498   }
1499   else
1500     interip.Perform(theS1,theD1,theS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep);
1501
1502   if (interip.IsDone()) 
1503   {
1504     done = Standard_True;
1505     empt = interip.IsEmpty();
1506
1507     if (!empt)
1508     {
1509       const Standard_Integer aNbLines = interip.NbLines();
1510       for(Standard_Integer i = 1; i <= aNbLines; i++)
1511       {
1512         if(interip.Line(i)->ArcType() != IntPatch_Walking)
1513           slin.Append(interip.Line(i));
1514       }
1515
1516       for(Standard_Integer i = 1; i <= aNbLines; i++)
1517       {
1518         if(interip.Line(i)->ArcType() == IntPatch_Walking)
1519           slin.Append(interip.Line(i));
1520       }
1521
1522       for (Standard_Integer i = 1; i <= interip.NbPnts(); i++)
1523         spnt.Append(interip.Point(i));
1524     }
1525   }
1526 }
1527
1528 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
1529                                     const Handle(Adaptor3d_TopolTool)& D1,
1530                                     const Handle(Adaptor3d_HSurface)&  S2,
1531                                     const Handle(Adaptor3d_TopolTool)& D2,
1532                                     const Standard_Real U1,
1533                                     const Standard_Real V1,
1534                                     const Standard_Real U2,
1535                                     const Standard_Real V2,
1536                                     const Standard_Real TolArc,
1537                                     const Standard_Real TolTang)
1538 {
1539   myTolArc = TolArc;
1540   myTolTang = TolTang;
1541   if(myFleche == 0.0) {
1542 #if DEBUG
1543     //cout<<" -- IntPatch_Intersection::myFleche fixe par defaut a 0.01 --"<<endl;
1544     //cout<<" -- Utiliser la Methode SetTolerances( ... ) "<<endl;
1545 #endif
1546     myFleche = 0.01;
1547   }
1548   if(myUVMaxStep==0.0) {
1549 #if DEBUG
1550     //cout<<" -- IntPatch_Intersection::myUVMaxStep fixe par defaut a 0.01 --"<<endl;
1551     //cout<<" -- Utiliser la Methode SetTolerances( ... ) "<<endl;
1552 #endif
1553     myUVMaxStep = 0.01;
1554   }
1555
1556   done = Standard_False;
1557   spnt.Clear();
1558   slin.Clear();
1559
1560   empt = Standard_True;
1561   tgte = Standard_False;
1562   oppo = Standard_False;
1563
1564   const GeomAbs_SurfaceType typs1 = S1->GetType();
1565   const GeomAbs_SurfaceType typs2 = S2->GetType();
1566   
1567   if(   typs1==GeomAbs_Plane 
1568      || typs1==GeomAbs_Cylinder
1569      || typs1==GeomAbs_Sphere
1570      || typs1==GeomAbs_Cone
1571      || typs2==GeomAbs_Plane 
1572      || typs2==GeomAbs_Cylinder
1573      || typs2==GeomAbs_Sphere
1574      || typs2==GeomAbs_Cone)
1575   {
1576     myIsStartPnt = Standard_True;
1577     myU1Start = U1; myV1Start = V1; myU2Start = U2; myV2Start = V2;
1578     Perform(S1,D1,S2,D2,TolArc,TolTang);
1579     myIsStartPnt = Standard_False;
1580   }
1581   else
1582   {
1583     IntPatch_PrmPrmIntersection interpp;
1584     interpp.Perform(S1,D1,S2,D2,U1,V1,U2,V2,TolTang,TolArc,myFleche,myUVMaxStep);
1585     if (interpp.IsDone())
1586     {
1587       done = Standard_True;
1588       tgte = Standard_False;
1589       empt = interpp.IsEmpty();
1590       const Standard_Integer nblm = interpp.NbLines();
1591       Standard_Integer i = 1;
1592       for (; i<=nblm; i++) slin.Append(interpp.Line(i));
1593     }
1594   }
1595
1596   for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
1597   {
1598     Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
1599
1600     if(aWL.IsNull())
1601       continue;
1602
1603     if (!aWL->IsPurgingAllowed())
1604       continue;
1605
1606     Handle(IntPatch_WLine) aRW =
1607       IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2, Standard_True);
1608
1609     if(aRW.IsNull())
1610       continue;
1611
1612     slin.InsertAfter(i, aRW);
1613     slin.Remove(i);
1614   }
1615 }
1616
1617 #ifdef DUMPOFIntPatch_Intersection
1618
1619 void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1,
1620                                   Handle(Adaptor2d_HCurve2d) *,
1621                                   int *NR1,
1622                                   int *,
1623                                   Standard_Integer nbR1,
1624                                   Standard_Integer ,
1625                                   const IntPatch_Point& VTX)
1626
1627   
1628   if(VTX.IsOnDomS1()) { 
1629     
1630     //-- long unsigned ptr= *((long unsigned *)(((Handle(Standard_Transient) *)(&(VTX.ArcOnS1())))));
1631     for(Standard_Integer i=0; i<nbR1;i++) { 
1632       if(VTX.ArcOnS1()==R1[i]) { 
1633         NR1[i]++;
1634         printf("\n ******************************");
1635         return;
1636       }
1637     }
1638     printf("\n R Pas trouvee  (IntPatch)\n");
1639     
1640   }
1641 }
1642 #endif
1643
1644 void IntPatch_Intersection::Dump(const Standard_Integer /*Mode*/,
1645                                  const Handle(Adaptor3d_HSurface)&  /*S1*/,
1646                                  const Handle(Adaptor3d_TopolTool)& /*D1*/,
1647                                  const Handle(Adaptor3d_HSurface)&  /*S2*/,
1648                                  const Handle(Adaptor3d_TopolTool)& /*D2*/) const 
1649
1650 #ifdef DUMPOFIntPatch_Intersection
1651   const int MAXR = 200;
1652   //-- ----------------------------------------------------------------------
1653   //--  construction de la liste des restrictions & vertex 
1654   //--
1655   int NR1[MAXR],NR2[MAXR];
1656   Handle(Adaptor2d_HCurve2d) R1[MAXR],R2[MAXR];
1657   Standard_Integer nbR1=0,nbR2=0;
1658   for(D1->Init();D1->More() && nbR1<MAXR; D1->Next()) { 
1659     R1[nbR1]=D1->Value(); 
1660     NR1[nbR1]=0;
1661     nbR1++;
1662   }
1663   for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) {
1664     R2[nbR2]=D2->Value();
1665     NR2[nbR2]=0;
1666     nbR2++;
1667   }
1668   
1669   printf("\nDUMP_INT:  ----empt:%2ud  tgte:%2ud  oppo:%2ud ---------------------------------",empt,tgte,empt);
1670   Standard_Integer i,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba;
1671   nbl=nbr=nbg=nbw=nba=nbgl=nbge=nbr1=nbr2=nbgc=nbgp=nbgh=0;
1672   nbl=NbLines();
1673   for(i=1;i<=nbl;i++) { 
1674     const Handle(IntPatch_Line)& line=Line(i);
1675     const IntPatch_IType IType=line->ArcType();
1676     if(IType == IntPatch_Walking) nbw++;
1677     else     if(IType == IntPatch_Restriction) { 
1678       nbr++;
1679       Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (line));
1680       if(rlin->IsArcOnS1()) nbr1++;
1681       if(rlin->IsArcOnS2()) nbr2++;
1682     }
1683     else     if(IType == IntPatch_Analytic) nba++;
1684     else     { 
1685       nbg++; 
1686       if(IType == IntPatch_Lin) nbgl++;
1687       else if(IType == IntPatch_Circle) nbgc++;
1688       else if(IType == IntPatch_Parabola) nbgp++;
1689       else if(IType == IntPatch_Hyperbola) nbgh++;
1690       else if(IType == IntPatch_Ellipse) nbge++;
1691     }
1692   }
1693   
1694   
1695   printf("\nDUMP_INT:Lines:%2d Wlin:%2d Restr:%2d(On1:%2d On2:%2d) Ana:%2d Geom:%2d(L:%2d C:%2d E:%2d H:%2d P:%2d)",
1696          nbl,nbw,nbr,nbr1,nbr2,nba,nbg,nbgl,nbgc,nbge,nbgh,nbgp);
1697   
1698   IntPatch_LineConstructor LineConstructor(2);
1699   
1700   Standard_Integer nbllc=0;
1701   nbw=nbr=nbg=nba=0;
1702   Standard_Integer nbva,nbvw,nbvr,nbvg;
1703   nbva=nbvr=nbvw=nbvg=0;
1704   for (j=1; j<=nbl; j++) {
1705     Standard_Integer v,nbvtx;
1706     const Handle(IntPatch_Line)& intersLinej = Line(j);
1707     Standard_Integer NbLines;
1708     LineConstructor.Perform(SequenceOfLine(),intersLinej,S1,D1,S2,D2,1e-7);
1709     NbLines = LineConstructor.NbLines();
1710     
1711     for(Standard_Integer k=1;k<=NbLines;k++) { 
1712       nbllc++;
1713       const Handle(IntPatch_Line)& LineK = LineConstructor.Line(k);
1714       if (LineK->ArcType() == IntPatch_Analytic) { 
1715         Handle(IntPatch_ALine) alin (Handle(IntPatch_ALine)::DownCast (LineK));
1716         nbvtx=alin->NbVertex();
1717         nbva+=nbvtx;        nba++;
1718         for(v=1;v<=nbvtx;v++) { 
1719           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,alin->Vertex(v));
1720         }
1721       }
1722       else if (LineK->ArcType() == IntPatch_Restriction) {
1723         Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (LineK));
1724         nbvtx=rlin->NbVertex();
1725         nbvr+=nbvtx;        nbr++;
1726         for(v=1;v<=nbvtx;v++) { 
1727           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,rlin->Vertex(v));
1728         }
1729       }
1730       else if (LineK->ArcType() == IntPatch_Walking) {
1731         Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (LineK));
1732         nbvtx=wlin->NbVertex();
1733         nbvw+=nbvtx;        nbw++;
1734         for(v=1;v<=nbvtx;v++) { 
1735           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,wlin->Vertex(v));
1736         }
1737       }
1738       else { 
1739         Handle(IntPatch_GLine) glin (Handle(IntPatch_GLine)::DownCast (LineK));
1740         nbvtx=glin->NbVertex();
1741         nbvg+=nbvtx;        nbg++;
1742         for(v=1;v<=nbvtx;v++) { 
1743           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,glin->Vertex(v));
1744         }
1745       }
1746     }
1747   }
1748   printf("\nDUMP_LC :Lines:%2d WLin:%2d Restr:%2d Ana:%2d Geom:%2d",
1749          nbllc,nbw,nbr,nba,nbg);
1750   printf("\nDUMP_LC :vtx          :%2d     r:%2d    :%2d     :%2d",
1751          nbvw,nbvr,nbva,nbvg);
1752
1753   printf("\n");
1754
1755 #endif 
1756 }