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