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