0026431: Can't cut a sphere from a cylinder
[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,TolArc,TolTang,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 =
558     GeomProjLib::Curve2d(C1Prj,Handle(Geom_Surface)::DownCast (GPln));
559   Handle(Geom2d_Curve) C2Prj2d =
560     GeomProjLib::Curve2d(C2Prj,Handle(Geom_Surface)::DownCast (GPln));
561   Geom2dAPI_InterCurveCurve ICC(C1Prj2d,C2Prj2d,1.0e-7);
562   if(ICC.NbPoints() > 0 )
563   {
564     for(Standard_Integer ip = 1; ip <= ICC.NbPoints(); ip++)
565     {
566       gp_Pnt2d P = ICC.Point(ip);
567       gp_Pnt P3d = ElCLib::To3d(gp_Ax2(puvS1,gp_Dir(DV)),P);
568       SP.Append(P3d);
569     }
570   }
571 }
572 //================================================================================
573 //function: FUN_NewFirstLast
574 //================================================================================
575 static void FUN_NewFirstLast(const GeomAbs_CurveType& ga_ct,
576                              const Standard_Real&     Fst,
577                              const Standard_Real&     Lst,
578                              const Standard_Real&     TrVal,
579                              Standard_Real&           NewFst,
580                              Standard_Real&           NewLst,
581                              Standard_Boolean&        NeedTr)
582 {
583   NewFst = Fst; NewLst = Lst; NeedTr = Standard_False;
584   switch (ga_ct)
585   {
586     case GeomAbs_Line:
587     case GeomAbs_Parabola:
588     {
589       if(Abs(Lst - Fst) > TrVal)
590       {
591         if(Fst >= 0. && Lst >= 0.)
592         {
593           NewFst = Fst;
594           NewLst = ((Fst + TrVal) < Lst) ? (Fst + TrVal) : Lst;
595         }
596         if(Fst < 0. && Lst < 0.)
597         {
598           NewLst = Lst;
599           NewFst = ((Lst - TrVal) > Fst) ? (Lst - TrVal) : Fst;
600         }
601         else
602         {
603           NewFst = (Fst < -TrVal) ? -TrVal : Fst;
604           NewLst = (Lst > TrVal) ? TrVal : Lst;
605         }
606         NeedTr = Standard_True;
607       }
608       break;
609     }
610     case GeomAbs_Hyperbola:
611     {
612       if(Abs(Lst - Fst) > 10.)
613       { 
614         if(Fst >= 0. && Lst >= 0.)
615         {
616           if(Fst > 4.) return;
617           NewFst = Fst;
618           NewLst = (Lst > 4.) ? 4. : Lst;
619         }
620         if(Fst < 0. && Lst < 0.)
621         {
622           if(Lst < -4.) return;
623           NewLst = Lst;
624           NewFst = (Fst < -4.) ? -4. : Fst;
625         }
626         else
627         {
628           NewFst = (Fst < -4.) ? -4. : Fst;
629           NewLst = (Lst > 4.) ? 4. : Lst;
630         }
631         NeedTr = Standard_True;
632       }
633       break;
634     }
635     default:
636     break;
637   }
638 }
639 //================================================================================
640 //function: FUN_TrimBothSurf
641 //================================================================================
642 static void FUN_TrimBothSurf(const Handle(Adaptor3d_HSurface)& S1,
643                              const GeomAbs_SurfaceType&        T1,
644                              const Handle(Adaptor3d_HSurface)& S2,
645                              const GeomAbs_SurfaceType&        T2,
646                              const Standard_Real&              TV,
647                              Handle(Adaptor3d_HSurface)&       NS1,
648                              Handle(Adaptor3d_HSurface)&       NS2)
649 {
650   const GeomAdaptor_Surface & gas1 = *(GeomAdaptor_Surface*)(&(S1->Surface()));
651   const GeomAdaptor_Surface & gas2 = *(GeomAdaptor_Surface*)(&(S2->Surface()));
652   const Handle(Geom_Surface) gs1 = gas1.Surface();
653   const Handle(Geom_Surface) gs2 = gas2.Surface();
654   const Standard_Real UM1 = 0.5 * (S1->LastUParameter() + S1->FirstUParameter());
655   const Standard_Real UM2 = 0.5 * (S2->LastUParameter() + S2->FirstUParameter());
656   const Standard_Real VM1 = 0.5 * (S1->LastVParameter() + S1->FirstVParameter());
657   const Standard_Real VM2 = 0.5 * (S2->LastVParameter() + S2->FirstVParameter());
658   Handle(Geom_Curve) visoS1, visoS2, uisoS1, uisoS2;
659   if(T1 != GeomAbs_OffsetSurface){ visoS1 = gs1->VIso(VM1); uisoS1 = gs1->UIso(UM1); }
660   else
661   {
662     const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs1);
663     const Handle(Geom_Surface) bs = gos->BasisSurface();
664     visoS1 = bs->VIso(VM1); uisoS1 = bs->UIso(UM1);
665   }
666   if(T2 != GeomAbs_OffsetSurface){ visoS2 = gs2->VIso(VM2); uisoS2 = gs2->UIso(UM2); }
667   else
668   {
669     const Handle(Geom_OffsetSurface) gos = Handle(Geom_OffsetSurface)::DownCast (gs2);
670     const Handle(Geom_Surface) bs = gos->BasisSurface();
671     visoS2 = bs->VIso(VM2); uisoS2 = bs->UIso(UM2);
672   }
673   if(uisoS1.IsNull() || uisoS2.IsNull() || visoS1.IsNull() || visoS2.IsNull()){ NS1 = S1; NS2 = S2; return; }
674   GeomAdaptor_Curve gau1(uisoS1);
675   GeomAdaptor_Curve gav1(visoS1);
676   GeomAdaptor_Curve gau2(uisoS2);
677   GeomAdaptor_Curve gav2(visoS2);
678   GeomAbs_CurveType GA_U1 = gau1.GetType();
679   GeomAbs_CurveType GA_V1 = gav1.GetType();
680   GeomAbs_CurveType GA_U2 = gau2.GetType();
681   GeomAbs_CurveType GA_V2 = gav2.GetType();
682   Standard_Boolean TrmU1 = Standard_False;
683   Standard_Boolean TrmV1 = Standard_False;
684   Standard_Boolean TrmU2 = Standard_False;
685   Standard_Boolean TrmV2 = Standard_False;
686   Standard_Real V1S1,V2S1,U1S1,U2S1, V1S2,V2S2,U1S2,U2S2;
687   FUN_NewFirstLast(GA_U1,S1->FirstVParameter(),S1->LastVParameter(),TV,V1S1,V2S1,TrmV1);
688   FUN_NewFirstLast(GA_V1,S1->FirstUParameter(),S1->LastUParameter(),TV,U1S1,U2S1,TrmU1);
689   FUN_NewFirstLast(GA_U2,S2->FirstVParameter(),S2->LastVParameter(),TV,V1S2,V2S2,TrmV2);
690   FUN_NewFirstLast(GA_V2,S2->FirstUParameter(),S2->LastUParameter(),TV,U1S2,U2S2,TrmU2);
691   if(TrmV1) NS1 = S1->VTrim(V1S1, V2S1, 1.0e-7);
692   if(TrmV2) NS2 = S2->VTrim(V1S2, V2S2, 1.0e-7);
693   if(TrmU1)
694   {
695     if(TrmV1)
696     {
697       Handle(Adaptor3d_HSurface) TS = NS1;
698       NS1 = TS->UTrim(U1S1, U2S1, 1.0e-7);
699     }
700     else NS1 = S1->UTrim(U1S1, U2S1, 1.0e-7);
701   }
702   if(TrmU2)
703   {
704     if(TrmV2)
705     {
706       Handle(Adaptor3d_HSurface) TS = NS2;
707       NS2 = TS->UTrim(U1S2, U2S2, 1.0e-7);
708     }
709     else NS2 = S2->UTrim(U1S2, U2S2, 1.0e-7);
710   }
711 }
712
713 //=======================================================================
714 //function : Perform
715 //purpose  : 
716 //=======================================================================
717 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
718                                     const Handle(Adaptor3d_TopolTool)& theD1,
719                                     const Handle(Adaptor3d_HSurface)&  theS2,
720                                     const Handle(Adaptor3d_TopolTool)& theD2,
721                                     const Standard_Real TolArc,
722                                     const Standard_Real TolTang,
723                                     const Standard_Boolean isGeomInt,
724                                     const Standard_Boolean theIsReqToKeepRLine,
725                                     const Standard_Boolean theIsReqToPostWLProc)
726 {
727   myTolArc = TolArc;
728   myTolTang = TolTang;
729   if(myFleche <= Precision::PConfusion())
730     myFleche = 0.01;
731   if(myUVMaxStep <= Precision::PConfusion())
732     myUVMaxStep = 0.01;
733
734   done = Standard_False;
735   spnt.Clear();
736   slin.Clear();
737   empt = Standard_True;
738   tgte = Standard_False;
739   oppo = Standard_False;
740
741   GeomAbs_SurfaceType typs1 = theS1->GetType();
742   GeomAbs_SurfaceType typs2 = theS2->GetType();
743   
744   //treatment of the cases with cone or torus
745   Standard_Boolean TreatAsBiParametric = Standard_False;
746   Standard_Integer bGeomGeom = 0;
747   //
748   if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone ||
749       typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
750     gp_Ax1 aCTAx, aGeomAx;
751     GeomAbs_SurfaceType aCTType;
752     Standard_Boolean bToCheck;
753     //
754     const Handle(Adaptor3d_HSurface)& aCTSurf = 
755       (typs1 == GeomAbs_Cone || typs1 == GeomAbs_Torus) ? theS1 : theS2;
756     const Handle(Adaptor3d_HSurface)& aGeomSurf = 
757       (typs1 == GeomAbs_Cone || typs1 == GeomAbs_Torus) ? theS2 : theS1;
758     //
759     aCTType = aCTSurf->GetType();
760     bToCheck = Standard_False;
761     //
762     if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone) {
763       const gp_Cone aCon1 = (aCTType == GeomAbs_Cone) ? 
764         aCTSurf->Cone() : aGeomSurf->Cone();
765       Standard_Real a1 = Abs(aCon1.SemiAngle());
766       bToCheck = (a1 < 0.02) || (a1 > 1.55);
767       //
768       if (typs1 == typs2) {
769         const gp_Cone aCon2 = aGeomSurf->Cone();
770         Standard_Real a2 = Abs(aCon2.SemiAngle());
771         bToCheck = bToCheck || (a2 < 0.02) || (a2 > 1.55);
772         //
773         if (a1 > 1.55 && a2 > 1.55) {//quasi-planes: if same domain, treat as canonic
774           const gp_Ax1 A1 = aCon1.Axis(), A2 = aCon2.Axis();
775           if (A1.IsParallel(A2,Precision::Angular())) {
776             const gp_Pnt Apex1 = aCon1.Apex(), Apex2 = aCon2.Apex();
777             const gp_Pln Plan1( Apex1, A1.Direction() );
778             if (Plan1.Distance( Apex2 ) <= Precision::Confusion()) {
779               bToCheck = Standard_False;
780             }
781           }
782         }
783       }
784       //
785       TreatAsBiParametric = bToCheck;
786       if (aCTType == GeomAbs_Cone) {
787         aCTAx = aCon1.Axis();
788       }
789     }
790     //
791     if (typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
792       const gp_Torus aTor1 = (aCTType == GeomAbs_Torus) ? 
793         aCTSurf->Torus() : aGeomSurf->Torus();
794       bToCheck = aTor1.MajorRadius() > aTor1.MinorRadius();
795       if (typs1 == typs2) {
796         const gp_Torus aTor2 = aGeomSurf->Torus();
797         bToCheck = aTor2.MajorRadius() > aTor2.MinorRadius();
798       }
799       //
800       if (aCTType == GeomAbs_Torus) {
801         aCTAx = aTor1.Axis();
802       }
803     }
804     //
805     if (bToCheck) {
806       const gp_Lin aL1(aCTAx);
807       //
808       switch (aGeomSurf->GetType()) {
809       case GeomAbs_Plane: {
810         aGeomAx = aGeomSurf->Plane().Axis();
811         if (aCTType == GeomAbs_Cone) {
812           bGeomGeom = 1;
813           if (Abs(aCTSurf->Cone().SemiAngle()) < 0.02) {
814             Standard_Real ps = Abs(aCTAx.Direction().Dot(aGeomAx.Direction()));
815             if(ps < 0.015) {
816               bGeomGeom = 0;
817             }
818           }
819         }
820         else {
821           if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) ||
822               (aCTAx.IsNormal(aGeomAx, Precision::Angular()) && 
823                (aGeomSurf->Plane().Distance(aCTAx.Location()) < Precision::Confusion()))) {
824             bGeomGeom = 1;
825           }
826         }
827         bToCheck = Standard_False;
828         break;
829       }
830       case GeomAbs_Sphere: {
831         if (aL1.Distance(aGeomSurf->Sphere().Location()) < Precision::Confusion()) {
832           bGeomGeom = 1;
833         }
834         bToCheck = Standard_False;
835         break;
836       }
837       case GeomAbs_Cylinder:
838         aGeomAx = aGeomSurf->Cylinder().Axis();
839         break;
840       case GeomAbs_Cone: 
841         aGeomAx = aGeomSurf->Cone().Axis();
842         break;
843       case GeomAbs_Torus: 
844         aGeomAx = aGeomSurf->Torus().Axis();
845         break;
846       default: 
847         bToCheck = Standard_False;
848         break;
849       }
850       //
851       if (bToCheck) {
852         if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) &&
853             (aL1.Distance(aGeomAx.Location()) <= Precision::Confusion())) {
854           bGeomGeom = 1;
855         }
856       }
857       //
858       if (bGeomGeom == 1) {
859         TreatAsBiParametric = Standard_False;
860       }
861     }
862   }
863   //
864
865   if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite()) {
866     TreatAsBiParametric= Standard_False;
867   }
868
869 //  Modified by skv - Mon Sep 26 14:58:30 2005 Begin
870 //   if(TreatAsBiParametric) { typs1 = typs2 = GeomAbs_BezierSurface; }
871   if(TreatAsBiParametric)
872   {
873     if (typs1 == GeomAbs_Cone && typs2 == GeomAbs_Plane)
874       typs1 = GeomAbs_BezierSurface; // Using Imp-Prm Intersector
875     else if (typs1 == GeomAbs_Plane && typs2 == GeomAbs_Cone)
876       typs2 = GeomAbs_BezierSurface; // Using Imp-Prm Intersector
877     else {
878       // Using Prm-Prm Intersector
879       typs1 = GeomAbs_BezierSurface;
880       typs2 = GeomAbs_BezierSurface;
881     }
882   }
883 //  Modified by skv - Mon Sep 26 14:58:30 2005 End
884
885   // Surface type definition
886   Standard_Integer ts1 = 0;
887   switch (typs1)
888   {
889     case GeomAbs_Plane:
890     case GeomAbs_Cylinder:
891     case GeomAbs_Sphere:
892     case GeomAbs_Cone: ts1 = 1; break;
893     case GeomAbs_Torus: ts1 = bGeomGeom; break;
894     default: break;
895   }
896
897   Standard_Integer ts2 = 0;
898   switch (typs2)
899   {
900     case GeomAbs_Plane:
901     case GeomAbs_Cylinder:
902     case GeomAbs_Sphere:
903     case GeomAbs_Cone: ts2 = 1; break;
904     case GeomAbs_Torus: ts2 = bGeomGeom; break;
905     default: break;
906   }
907   //
908   // treatment of the cases with torus and any other geom surface
909   //
910   // Possible intersection types: 1. ts1 == ts2 == 1 <Geom-Geom>
911   //                              2. ts1 != ts2      <Geom-Param>
912   //                              3. ts1 == ts2 == 0 <Param-Param>
913
914   // Geom - Geom
915   if(ts1 == ts2 && ts1 == 1)
916   {
917     const Standard_Boolean RestrictLine = Standard_True;
918     IntSurf_ListOfPntOn2S ListOfPnts;
919     ListOfPnts.Clear();
920     if(isGeomInt)
921     {
922       if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite())
923       {
924         GeomGeomPerfom( theS1, theD1, theS2, theD2, TolArc, 
925                         TolTang, ListOfPnts, RestrictLine,
926                         typs1, typs2, theIsReqToKeepRLine);
927       }
928       else
929       {
930         GeomGeomPerfomTrimSurf( theS1, theD1, theS2, theD2,
931                                 TolArc, TolTang, ListOfPnts, RestrictLine,
932                                 typs1, typs2, theIsReqToKeepRLine);
933       }
934     }
935     else
936     {
937       ParamParamPerfom(theS1, theD1, theS2, theD2, 
938               TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
939     }
940   }
941
942   // Geom - Param
943   if(ts1 != ts2)
944   {
945     GeomParamPerfom(theS1, theD1, theS2, theD2, ts1 == 0, typs1, typs2);
946   }
947
948   // Param - Param 
949   if(ts1 == ts2 && ts1 == 0)
950   {
951     const Standard_Boolean RestrictLine = Standard_True;
952     IntSurf_ListOfPntOn2S ListOfPnts;
953     ListOfPnts.Clear();
954
955     ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
956                         TolTang, ListOfPnts, RestrictLine, typs1, typs2);
957   }
958
959   if(!theIsReqToPostWLProc)
960     return;
961
962   for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
963   {
964     Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
965
966     if(aWL.IsNull())
967       continue;
968
969     Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
970
971     if(aRW.IsNull())
972       continue;
973
974     slin.InsertAfter(i, aRW);
975     slin.Remove(i);
976   }
977 }
978
979 //=======================================================================
980 //function : Perform
981 //purpose  : 
982 //=======================================================================
983 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  theS1,
984                                     const Handle(Adaptor3d_TopolTool)& theD1,
985                                     const Handle(Adaptor3d_HSurface)&  theS2,
986                                     const Handle(Adaptor3d_TopolTool)& theD2,
987                                     const Standard_Real TolArc,
988                                     const Standard_Real TolTang,
989                                     IntSurf_ListOfPntOn2S& ListOfPnts,
990                                     const Standard_Boolean RestrictLine,
991                                     const Standard_Boolean isGeomInt,
992                                     const Standard_Boolean theIsReqToKeepRLine,
993                                     const Standard_Boolean theIsReqToPostWLProc)
994 {
995   myTolArc = TolArc;
996   myTolTang = TolTang;
997   if(myFleche <= Precision::PConfusion())
998     myFleche = 0.01;
999   if(myUVMaxStep <= Precision::PConfusion())
1000     myUVMaxStep = 0.01;
1001     
1002   done = Standard_False;
1003   spnt.Clear();
1004   slin.Clear();
1005   empt = Standard_True;
1006   tgte = Standard_False;
1007   oppo = Standard_False;
1008
1009   GeomAbs_SurfaceType typs1 = theS1->GetType();
1010   GeomAbs_SurfaceType typs2 = theS2->GetType();
1011   //
1012   //treatment of the cases with cone or torus
1013   Standard_Boolean TreatAsBiParametric = Standard_False;
1014   Standard_Integer bGeomGeom = 0;
1015   //
1016   if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone ||
1017       typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
1018     gp_Ax1 aCTAx, aGeomAx;
1019     GeomAbs_SurfaceType aCTType;
1020     Standard_Boolean bToCheck;
1021     //
1022     const Handle(Adaptor3d_HSurface)& aCTSurf = 
1023       (typs1 == GeomAbs_Cone || typs1 == GeomAbs_Torus) ? theS1 : theS2;
1024     const Handle(Adaptor3d_HSurface)& aGeomSurf = 
1025       (typs1 == GeomAbs_Cone || typs1 == GeomAbs_Torus) ? theS2 : theS1;
1026     //
1027     aCTType = aCTSurf->GetType();
1028     bToCheck = Standard_False;
1029     //
1030     if (typs1 == GeomAbs_Cone  || typs2 == GeomAbs_Cone) {
1031       const gp_Cone aCon1 = (aCTType == GeomAbs_Cone) ? 
1032         aCTSurf->Cone() : aGeomSurf->Cone();
1033       Standard_Real a1 = Abs(aCon1.SemiAngle());
1034       bToCheck = (a1 < 0.02) || (a1 > 1.55);
1035       //
1036       if (typs1 == typs2) {
1037         const gp_Cone aCon2 = aGeomSurf->Cone();
1038         Standard_Real a2 = Abs(aCon2.SemiAngle());
1039         bToCheck = bToCheck || (a2 < 0.02) || (a2 > 1.55);
1040         //
1041         if (a1 > 1.55 && a2 > 1.55) {//quasi-planes: if same domain, treat as canonic
1042           const gp_Ax1 A1 = aCon1.Axis(), A2 = aCon2.Axis();
1043           if (A1.IsParallel(A2,Precision::Angular())) {
1044             const gp_Pnt Apex1 = aCon1.Apex(), Apex2 = aCon2.Apex();
1045             const gp_Pln Plan1( Apex1, A1.Direction() );
1046             if (Plan1.Distance( Apex2 ) <= Precision::Confusion()) {
1047               bToCheck = Standard_False;
1048             }
1049           }
1050         }
1051       }
1052       //
1053       TreatAsBiParametric = bToCheck;
1054       if (aCTType == GeomAbs_Cone) {
1055         aCTAx = aCon1.Axis();
1056       }
1057     }
1058     //
1059     if (typs1 == GeomAbs_Torus || typs2 == GeomAbs_Torus) {
1060       const gp_Torus aTor1 = (aCTType == GeomAbs_Torus) ? 
1061         aCTSurf->Torus() : aGeomSurf->Torus();
1062       bToCheck = aTor1.MajorRadius() > aTor1.MinorRadius();
1063       if (typs1 == typs2) {
1064         const gp_Torus aTor2 = aGeomSurf->Torus();
1065         bToCheck = aTor2.MajorRadius() > aTor2.MinorRadius();
1066       }
1067       //
1068       if (aCTType == GeomAbs_Torus) {
1069         aCTAx = aTor1.Axis();
1070       }
1071     }
1072     //
1073     if (bToCheck) {
1074       const gp_Lin aL1(aCTAx);
1075       //
1076       switch (aGeomSurf->GetType()) {
1077       case GeomAbs_Plane: {
1078         aGeomAx = aGeomSurf->Plane().Axis();
1079         if (aCTType == GeomAbs_Cone) {
1080           bGeomGeom = 1;
1081           if (Abs(aCTSurf->Cone().SemiAngle()) < 0.02) {
1082             Standard_Real ps = Abs(aCTAx.Direction().Dot(aGeomAx.Direction()));
1083             if(ps < 0.015) {
1084               bGeomGeom = 0;
1085             }
1086           }
1087         }
1088         else {
1089           if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) ||
1090               (aCTAx.IsNormal(aGeomAx, Precision::Angular()) && 
1091                (aGeomSurf->Plane().Distance(aCTAx.Location()) < Precision::Confusion()))) {
1092             bGeomGeom = 1;
1093           }
1094         }
1095         bToCheck = Standard_False;
1096         break;
1097       }
1098       case GeomAbs_Sphere: {
1099         if (aL1.Distance(aGeomSurf->Sphere().Location()) < Precision::Confusion()) {
1100           bGeomGeom = 1;
1101         }
1102         bToCheck = Standard_False;
1103         break;
1104       }
1105       case GeomAbs_Cylinder:
1106         aGeomAx = aGeomSurf->Cylinder().Axis();
1107         break;
1108       case GeomAbs_Cone: 
1109         aGeomAx = aGeomSurf->Cone().Axis();
1110         break;
1111       case GeomAbs_Torus: 
1112         aGeomAx = aGeomSurf->Torus().Axis();
1113         break;
1114       default: 
1115         bToCheck = Standard_False;
1116         break;
1117       }
1118       //
1119       if (bToCheck) {
1120         if (aCTAx.IsParallel(aGeomAx, Precision::Angular()) &&
1121             (aL1.Distance(aGeomAx.Location()) <= Precision::Confusion())) {
1122           bGeomGeom = 1;
1123         }
1124       }
1125       //
1126       if (bGeomGeom == 1) {
1127         TreatAsBiParametric = Standard_False;
1128       }
1129     }
1130   }
1131   //
1132
1133   if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite()) {
1134     TreatAsBiParametric= Standard_False;
1135   }
1136
1137   if(TreatAsBiParametric)
1138   {
1139     // Using Prm-Prm Intersector
1140     typs1 = GeomAbs_BezierSurface;
1141     typs2 = GeomAbs_BezierSurface;
1142   }
1143
1144   // Surface type definition
1145   Standard_Integer ts1 = 0;
1146   switch (typs1)
1147   {
1148     case GeomAbs_Plane:
1149     case GeomAbs_Cylinder:
1150     case GeomAbs_Sphere:
1151     case GeomAbs_Cone: ts1 = 1; break;
1152     case GeomAbs_Torus: ts1 = bGeomGeom; break;
1153     default: break;
1154   }
1155
1156   Standard_Integer ts2 = 0;
1157   switch (typs2)
1158   {
1159     case GeomAbs_Plane:
1160     case GeomAbs_Cylinder:
1161     case GeomAbs_Sphere:
1162     case GeomAbs_Cone: ts2 = 1; break;
1163     case GeomAbs_Torus: ts2 = bGeomGeom; break;
1164     default: break;
1165   }
1166   //
1167   // Possible intersection types: 1. ts1 == ts2 == 1 <Geom-Geom>
1168   //                              2. ts1 != ts2      <Geom-Param>
1169   //                              3. ts1 == ts2 == 0 <Param-Param>
1170
1171   if(!isGeomInt)
1172   {
1173     ParamParamPerfom(theS1, theD1, theS2, theD2, 
1174                 TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
1175   }
1176   else if(ts1 != ts2)
1177   {
1178     GeomParamPerfom(theS1, theD1, theS2, theD2, ts1 == 0, typs1, typs2);
1179   }
1180   else if (ts1 == 0)
1181   {
1182     ParamParamPerfom(theS1, theD1, theS2, theD2,
1183                 TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2);
1184   }
1185   else if(ts1 == 1)
1186   {
1187     if(theD1->DomainIsInfinite() || theD2->DomainIsInfinite())
1188     {
1189       GeomGeomPerfom(theS1, theD1, theS2, theD2, TolArc, 
1190                       TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
1191     }
1192     else
1193     {
1194       GeomGeomPerfomTrimSurf(theS1, theD1, theS2, theD2,
1195               TolArc, TolTang, ListOfPnts, RestrictLine, typs1, typs2, theIsReqToKeepRLine);
1196     }
1197   }
1198
1199   if(!theIsReqToPostWLProc)
1200     return;
1201
1202   for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
1203   {
1204     Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
1205
1206     if(aWL.IsNull())
1207       continue;
1208
1209     Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
1210
1211     if(aRW.IsNull())
1212       continue;
1213
1214     slin.InsertAfter(i, aRW);
1215     slin.Remove(i);
1216   }
1217 }
1218
1219 //=======================================================================
1220 //function : ParamParamPerfom
1221 //purpose  : 
1222 //=======================================================================
1223 void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
1224                                              const Handle(Adaptor3d_TopolTool)& theD1,
1225                                              const Handle(Adaptor3d_HSurface)&  theS2,
1226                                              const Handle(Adaptor3d_TopolTool)& theD2,
1227                                              const Standard_Real TolArc,
1228                                              const Standard_Real TolTang,
1229                                              IntSurf_ListOfPntOn2S& ListOfPnts,
1230                                              const Standard_Boolean RestrictLine,
1231                                              const GeomAbs_SurfaceType typs1,
1232                                              const GeomAbs_SurfaceType typs2)
1233 {
1234   IntPatch_PrmPrmIntersection interpp;
1235   if(!theD1->DomainIsInfinite() && !theD2->DomainIsInfinite())
1236   {
1237     Standard_Boolean ClearFlag = Standard_True;
1238     if(!ListOfPnts.IsEmpty())
1239     {
1240       interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
1241       ClearFlag = Standard_False;
1242     }
1243     interpp.Perform(theS1,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep,ClearFlag);   //double call!!!!!!!
1244   }
1245   else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
1246   {
1247     gp_Pnt pMaxXYZ, pMinXYZ;
1248     if(theD1->DomainIsInfinite())
1249     {
1250       FUN_GetMinMaxXYZPnt( theS2, pMinXYZ, pMaxXYZ );
1251       const Standard_Real MU = Max(Abs(theS2->FirstUParameter()),Abs(theS2->LastUParameter()));
1252       const Standard_Real MV = Max(Abs(theS2->FirstVParameter()),Abs(theS2->LastVParameter()));
1253       const Standard_Real AP = Max(MU, MV);
1254       Handle(Adaptor3d_HSurface) SS;
1255       FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS1, AP, SS);
1256       interpp.Perform(SS,theD1,theS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep);
1257     }
1258     else
1259     {
1260       FUN_GetMinMaxXYZPnt( theS1, pMinXYZ, pMaxXYZ );
1261       const Standard_Real MU = Max(Abs(theS1->FirstUParameter()),Abs(theS1->LastUParameter()));
1262       const Standard_Real MV = Max(Abs(theS1->FirstVParameter()),Abs(theS1->LastVParameter()));
1263       const Standard_Real AP = Max(MU, MV);
1264       Handle(Adaptor3d_HSurface) SS;
1265       FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS2, AP, SS);
1266       interpp.Perform(theS1, theD1, SS, theD2,TolArc,TolTang,myFleche,myUVMaxStep);
1267     }
1268   }//(theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite())
1269   else
1270   {
1271     if(typs1 == GeomAbs_OtherSurface || typs2 == GeomAbs_OtherSurface)
1272     {
1273       done = Standard_False;
1274       return;
1275     }
1276
1277     Standard_Boolean IsPLInt = Standard_False;
1278     TColgp_SequenceOfPnt sop;
1279     gp_Vec v;
1280     FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v);
1281
1282     if(IsPLInt)
1283     {
1284       if(sop.Length() > 0)
1285       {
1286         for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
1287         {
1288           gp_Lin lin(sop.Value(ip),gp_Dir(v));
1289           Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
1290           slin.Append(Handle(IntPatch_Line)::DownCast (gl));
1291         }
1292
1293         done = Standard_True;
1294       }
1295       else
1296         done = Standard_False;
1297
1298       return;
1299     }// 'COLLINEAR LINES'
1300     else
1301     {
1302       Handle(Adaptor3d_HSurface) nS1 = theS1;
1303       Handle(Adaptor3d_HSurface) nS2 = theS2;
1304       FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+8,nS1,nS2);
1305       interpp.Perform(nS1,theD1,nS2,theD2,TolArc,TolTang,myFleche,myUVMaxStep);
1306     }// 'NON - COLLINEAR LINES'
1307   }// both domains are infinite
1308
1309   if (interpp.IsDone())
1310   {
1311     done = Standard_True;
1312     tgte = Standard_False;
1313     empt = interpp.IsEmpty();
1314
1315     for(Standard_Integer i = 1; i <= interpp.NbLines(); i++)
1316     {
1317       if(interpp.Line(i)->ArcType() != IntPatch_Walking)
1318         slin.Append(interpp.Line(i));
1319     }
1320
1321     for (Standard_Integer i = 1; i <= interpp.NbLines(); i++)
1322     {
1323       if(interpp.Line(i)->ArcType() == IntPatch_Walking)
1324         slin.Append(interpp.Line(i));
1325     }
1326   }
1327 }
1328
1329 //=======================================================================
1330 ////function : GeomGeomPerfom
1331 //purpose  : 
1332 //=======================================================================
1333 void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& theS1,
1334                                            const Handle(Adaptor3d_TopolTool)& theD1,
1335                                            const Handle(Adaptor3d_HSurface)& theS2,
1336                                            const Handle(Adaptor3d_TopolTool)& theD2,
1337                                            const Standard_Real TolArc,
1338                                            const Standard_Real TolTang,
1339                                            IntSurf_ListOfPntOn2S& ListOfPnts,
1340                                            const Standard_Boolean RestrictLine,
1341                                            const GeomAbs_SurfaceType theTyps1,
1342                                            const GeomAbs_SurfaceType theTyps2,
1343                                            const Standard_Boolean theIsReqToKeepRLine)
1344 {
1345   IntPatch_ImpImpIntersection interii(theS1,theD1,theS2,theD2,
1346                                       myTolArc,myTolTang, theIsReqToKeepRLine);
1347   const Standard_Boolean anIS = interii.IsDone();
1348   if (anIS)
1349   {
1350     done = anIS;
1351     empt = interii.IsEmpty();
1352     if (!empt)
1353     {
1354       tgte = interii.TangentFaces();
1355       if (tgte)
1356         oppo = interii.OppositeFaces();
1357
1358       for (Standard_Integer i = 1; i <= interii.NbLines(); i++)
1359       {
1360         const Handle(IntPatch_Line)& line = interii.Line(i);
1361         if (line->ArcType() == IntPatch_Analytic)
1362         {
1363           const GeomAbs_SurfaceType aTyps1 = theS1->GetType();
1364           const GeomAbs_SurfaceType aTyps2 = theS2->GetType();
1365           IntSurf_Quadric Quad1,Quad2;
1366           
1367           switch(aTyps1)
1368           {
1369           case GeomAbs_Plane:
1370             Quad1.SetValue(theS1->Plane());
1371             break;
1372
1373           case GeomAbs_Cylinder:
1374             Quad1.SetValue(theS1->Cylinder());
1375             break;
1376
1377           case GeomAbs_Sphere:
1378             Quad1.SetValue(theS1->Sphere());
1379             break;
1380
1381           case GeomAbs_Cone:
1382             Quad1.SetValue(theS1->Cone());
1383             break;
1384
1385           case GeomAbs_Torus:
1386             Quad1.SetValue(theS1->Torus());
1387             break;
1388
1389           default:
1390             break;
1391           }
1392
1393           switch(aTyps2)
1394           {
1395           case GeomAbs_Plane:
1396             Quad2.SetValue(theS2->Plane());
1397             break;
1398           case GeomAbs_Cylinder:
1399             Quad2.SetValue(theS2->Cylinder());
1400             break;
1401
1402           case GeomAbs_Sphere:
1403             Quad2.SetValue(theS2->Sphere());
1404             break;
1405
1406           case GeomAbs_Cone:
1407             Quad2.SetValue(theS2->Cone());
1408             break;
1409
1410           case GeomAbs_Torus:
1411             Quad2.SetValue(theS2->Torus());
1412             break;
1413
1414           default:
1415             break;
1416           }
1417
1418           IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,aNbPointsInALine);
1419           Handle(IntPatch_Line) wlin=AToW.MakeWLine((*((Handle(IntPatch_ALine) *)(&line))));
1420           slin.Append(wlin);
1421         }
1422         else
1423           slin.Append(interii.Line(i));
1424       }
1425
1426       for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)
1427       {
1428         spnt.Append(interii.Point(i));
1429       }
1430     }
1431   }
1432   else
1433     ParamParamPerfom(theS1, theD1, theS2, theD2, 
1434                 TolArc, TolTang, ListOfPnts, RestrictLine, theTyps1, theTyps2);
1435 }
1436
1437 //=======================================================================
1438 //function : GeomParamPerfom
1439 //purpose  : 
1440 //=======================================================================
1441 void IntPatch_Intersection::
1442   GeomParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
1443                   const Handle(Adaptor3d_TopolTool)& theD1,
1444                   const Handle(Adaptor3d_HSurface)&  theS2,
1445                   const Handle(Adaptor3d_TopolTool)& theD2,
1446                   const Standard_Boolean isNotAnalitical,
1447                   const GeomAbs_SurfaceType typs1,
1448                   const GeomAbs_SurfaceType typs2)
1449 {
1450   IntPatch_ImpPrmIntersection interip;
1451   if (myIsStartPnt)
1452   {
1453     if (isNotAnalitical/*ts1 == 0*/)
1454       interip.SetStartPoint(myU1Start,myV1Start);
1455     else
1456       interip.SetStartPoint(myU2Start,myV2Start);
1457   }
1458
1459   if(theD1->DomainIsInfinite() && theD2->DomainIsInfinite())
1460   {
1461     Standard_Boolean IsPLInt = Standard_False;
1462     TColgp_SequenceOfPnt sop;
1463     gp_Vec v;
1464     FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v);
1465     
1466     if(IsPLInt)
1467     {
1468       if(sop.Length() > 0)
1469       {
1470         for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
1471         {
1472           gp_Lin lin(sop.Value(ip),gp_Dir(v));
1473           Handle(IntPatch_GLine) gl = new IntPatch_GLine(lin,Standard_False);
1474           slin.Append(Handle(IntPatch_Line)::DownCast (gl));
1475         }
1476
1477         done = Standard_True;
1478       }
1479       else
1480         done = Standard_False;
1481
1482       return;
1483     }
1484     else
1485     {
1486       Handle(Adaptor3d_HSurface) nS1 = theS1;
1487       Handle(Adaptor3d_HSurface) nS2 = theS2;
1488       FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+5,nS1,nS2);
1489       interip.Perform(nS1,theD1,nS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep);
1490     }
1491   }
1492   else
1493     interip.Perform(theS1,theD1,theS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep);
1494
1495   if (interip.IsDone()) 
1496   {
1497     done = Standard_True;
1498     empt = interip.IsEmpty();
1499
1500     if (!empt)
1501     {
1502       const Standard_Integer aNbLines = interip.NbLines();
1503       for(Standard_Integer i = 1; i <= aNbLines; i++)
1504       {
1505         if(interip.Line(i)->ArcType() != IntPatch_Walking)
1506           slin.Append(interip.Line(i));
1507       }
1508
1509       for(Standard_Integer i = 1; i <= aNbLines; i++)
1510       {
1511         if(interip.Line(i)->ArcType() == IntPatch_Walking)
1512           slin.Append(interip.Line(i));
1513       }
1514
1515       for (Standard_Integer i = 1; i <= interip.NbPnts(); i++)
1516         spnt.Append(interip.Point(i));
1517     }
1518   }
1519 }
1520
1521 //=======================================================================
1522 //function : GeomGeomPerfomTrimSurf
1523 //purpose  : This function returns ready walking-line (which is not need
1524 //            in convertation) as an intersection line between two
1525 //            trimmed surfaces.
1526 //=======================================================================
1527 void IntPatch_Intersection::
1528   GeomGeomPerfomTrimSurf( const Handle(Adaptor3d_HSurface)& theS1,
1529                           const Handle(Adaptor3d_TopolTool)& theD1,
1530                           const Handle(Adaptor3d_HSurface)& theS2,
1531                           const Handle(Adaptor3d_TopolTool)& theD2,
1532                           const Standard_Real theTolArc,
1533                           const Standard_Real theTolTang,
1534                           IntSurf_ListOfPntOn2S& theListOfPnts,
1535                           const Standard_Boolean RestrictLine,
1536                           const GeomAbs_SurfaceType theTyps1,
1537                           const GeomAbs_SurfaceType theTyps2,
1538                           const Standard_Boolean theIsReqToKeepRLine)
1539 {
1540   IntSurf_Quadric Quad1,Quad2;
1541
1542   if((theTyps1 == GeomAbs_Cylinder) && (theTyps2 == GeomAbs_Cylinder))
1543   {
1544     IntPatch_ImpImpIntersection anInt;
1545     anInt.Perform(theS1, theD1, theS2, theD2, myTolArc,
1546                   myTolTang, Standard_True, theIsReqToKeepRLine);
1547
1548     done = anInt.IsDone();
1549
1550     if(done)
1551     {
1552       empt = anInt.IsEmpty();
1553       if (!empt)
1554       {
1555         tgte = anInt.TangentFaces();
1556         if (tgte)
1557           oppo = anInt.OppositeFaces();
1558
1559         const Standard_Integer aNbLin = anInt.NbLines();
1560         const Standard_Integer aNbPts = anInt.NbPnts();
1561
1562         for(Standard_Integer aLID = 1; aLID <= aNbLin; aLID++)
1563         {
1564           const Handle(IntPatch_Line)& aLine = anInt.Line(aLID);
1565           slin.Append(aLine);
1566         }
1567
1568         for(Standard_Integer aPID = 1; aPID <= aNbPts; aPID++)
1569         {
1570           const IntPatch_Point& aPoint = anInt.Point(aPID);
1571           spnt.Append(aPoint);
1572         }
1573
1574         IntPatch_WLineTool::JoinWLines( slin, spnt, theTolTang,
1575                                         theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
1576                                         theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
1577                                         theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
1578                                         theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
1579                                         theS1->FirstUParameter(),
1580                                         theS1->LastUParameter(),
1581                                         theS1->FirstVParameter(),
1582                                         theS1->LastVParameter(),
1583                                         theS2->FirstUParameter(),
1584                                         theS2->LastUParameter(),
1585                                         theS2->FirstVParameter(),
1586                                         theS2->LastVParameter());
1587       }
1588     }
1589   }
1590   else
1591   {
1592     GeomGeomPerfom(theS1, theD1, theS2, theD2,
1593             theTolArc, theTolTang, theListOfPnts,
1594             RestrictLine, theTyps1, theTyps2, theIsReqToKeepRLine);
1595   }
1596 }
1597
1598
1599 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
1600                                     const Handle(Adaptor3d_TopolTool)& D1,
1601                                     const Handle(Adaptor3d_HSurface)&  S2,
1602                                     const Handle(Adaptor3d_TopolTool)& D2,
1603                                     const Standard_Real U1,
1604                                     const Standard_Real V1,
1605                                     const Standard_Real U2,
1606                                     const Standard_Real V2,
1607                                     const Standard_Real TolArc,
1608                                     const Standard_Real TolTang)
1609 {
1610   myTolArc = TolArc;
1611   myTolTang = TolTang;
1612   if(myFleche == 0.0) {
1613 #if DEBUG
1614     //cout<<" -- IntPatch_Intersection::myFleche fixe par defaut a 0.01 --"<<endl;
1615     //cout<<" -- Utiliser la Methode SetTolerances( ... ) "<<endl;
1616 #endif
1617     myFleche = 0.01;
1618   }
1619   if(myUVMaxStep==0.0) {
1620 #if DEBUG
1621     //cout<<" -- IntPatch_Intersection::myUVMaxStep fixe par defaut a 0.01 --"<<endl;
1622     //cout<<" -- Utiliser la Methode SetTolerances( ... ) "<<endl;
1623 #endif
1624     myUVMaxStep = 0.01;
1625   }
1626
1627   done = Standard_False;
1628   spnt.Clear();
1629   slin.Clear();
1630
1631   empt = Standard_True;
1632   tgte = Standard_False;
1633   oppo = Standard_False;
1634
1635   const GeomAbs_SurfaceType typs1 = S1->GetType();
1636   const GeomAbs_SurfaceType typs2 = S2->GetType();
1637   
1638   if(   typs1==GeomAbs_Plane 
1639      || typs1==GeomAbs_Cylinder
1640      || typs1==GeomAbs_Sphere
1641      || typs1==GeomAbs_Cone
1642      || typs2==GeomAbs_Plane 
1643      || typs2==GeomAbs_Cylinder
1644      || typs2==GeomAbs_Sphere
1645      || typs2==GeomAbs_Cone)
1646   {
1647     myIsStartPnt = Standard_True;
1648     myU1Start = U1; myV1Start = V1; myU2Start = U2; myV2Start = V2;
1649     Perform(S1,D1,S2,D2,TolArc,TolTang);
1650     myIsStartPnt = Standard_False;
1651   }
1652   else
1653   {
1654     IntPatch_PrmPrmIntersection interpp;
1655     interpp.Perform(S1,D1,S2,D2,U1,V1,U2,V2,TolArc,TolTang,myFleche,myUVMaxStep);
1656     if (interpp.IsDone())
1657     {
1658       done = Standard_True;
1659       tgte = Standard_False;
1660       empt = interpp.IsEmpty();
1661       const Standard_Integer nblm = interpp.NbLines();
1662       Standard_Integer i = 1;
1663       for (; i<=nblm; i++) slin.Append(interpp.Line(i));
1664     }
1665   }
1666
1667   for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
1668   {
1669     Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
1670
1671     if(aWL.IsNull())
1672       continue;
1673
1674     Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2);
1675
1676     if(aRW.IsNull())
1677       continue;
1678
1679     slin.InsertAfter(i, aRW);
1680     slin.Remove(i);
1681   }
1682 }
1683
1684 #ifdef DUMPOFIntPatch_Intersection
1685
1686 void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1,
1687                                   Handle(Adaptor2d_HCurve2d) *,
1688                                   int *NR1,
1689                                   int *,
1690                                   Standard_Integer nbR1,
1691                                   Standard_Integer ,
1692                                   const IntPatch_Point& VTX)
1693
1694   
1695   if(VTX.IsOnDomS1()) { 
1696     
1697     //-- long unsigned ptr= *((long unsigned *)(((Handle(Standard_Transient) *)(&(VTX.ArcOnS1())))));
1698     for(Standard_Integer i=0; i<nbR1;i++) { 
1699       if(VTX.ArcOnS1()==R1[i]) { 
1700         NR1[i]++;
1701         printf("\n ******************************");
1702         return;
1703       }
1704     }
1705     printf("\n R Pas trouvee  (IntPatch)\n");
1706     
1707   }
1708 }
1709 #endif
1710
1711 void IntPatch_Intersection::Dump(const Standard_Integer /*Mode*/,
1712                                  const Handle(Adaptor3d_HSurface)&  /*S1*/,
1713                                  const Handle(Adaptor3d_TopolTool)& /*D1*/,
1714                                  const Handle(Adaptor3d_HSurface)&  /*S2*/,
1715                                  const Handle(Adaptor3d_TopolTool)& /*D2*/) const 
1716
1717 #ifdef DUMPOFIntPatch_Intersection
1718   const int MAXR = 200;
1719   //-- ----------------------------------------------------------------------
1720   //--  construction de la liste des restrictions & vertex 
1721   //--
1722   int NR1[MAXR],NR2[MAXR];
1723   Handle(Adaptor2d_HCurve2d) R1[MAXR],R2[MAXR];
1724   Standard_Integer nbR1=0,nbR2=0;
1725   for(D1->Init();D1->More() && nbR1<MAXR; D1->Next()) { 
1726     R1[nbR1]=D1->Value(); 
1727     NR1[nbR1]=0;
1728     nbR1++;
1729   }
1730   for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) {
1731     R2[nbR2]=D2->Value();
1732     NR2[nbR2]=0;
1733     nbR2++;
1734   }
1735   
1736   printf("\nDUMP_INT:  ----empt:%2ud  tgte:%2ud  oppo:%2ud ---------------------------------",empt,tgte,empt);
1737   Standard_Integer i,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba;
1738   nbl=nbr=nbg=nbw=nba=nbgl=nbge=nbr1=nbr2=nbgc=nbgp=nbgh=0;
1739   nbl=NbLines();
1740   for(i=1;i<=nbl;i++) { 
1741     const Handle(IntPatch_Line)& line=Line(i);
1742     const IntPatch_IType IType=line->ArcType();
1743     if(IType == IntPatch_Walking) nbw++;
1744     else     if(IType == IntPatch_Restriction) { 
1745       nbr++;
1746       Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (line));
1747       if(rlin->IsArcOnS1()) nbr1++;
1748       if(rlin->IsArcOnS2()) nbr2++;
1749     }
1750     else     if(IType == IntPatch_Analytic) nba++;
1751     else     { 
1752       nbg++; 
1753       if(IType == IntPatch_Lin) nbgl++;
1754       else if(IType == IntPatch_Circle) nbgc++;
1755       else if(IType == IntPatch_Parabola) nbgp++;
1756       else if(IType == IntPatch_Hyperbola) nbgh++;
1757       else if(IType == IntPatch_Ellipse) nbge++;
1758     }
1759   }
1760   
1761   
1762   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)",
1763          nbl,nbw,nbr,nbr1,nbr2,nba,nbg,nbgl,nbgc,nbge,nbgh,nbgp);
1764   
1765   IntPatch_LineConstructor LineConstructor(2);
1766   
1767   Standard_Integer nbllc=0;
1768   nbw=nbr=nbg=nba=0;
1769   Standard_Integer nbva,nbvw,nbvr,nbvg;
1770   nbva=nbvr=nbvw=nbvg=0;
1771   for (j=1; j<=nbl; j++) {
1772     Standard_Integer v,nbvtx;
1773     const Handle(IntPatch_Line)& intersLinej = Line(j);
1774     Standard_Integer NbLines;
1775     LineConstructor.Perform(SequenceOfLine(),intersLinej,S1,D1,S2,D2,1e-7);
1776     NbLines = LineConstructor.NbLines();
1777     
1778     for(Standard_Integer k=1;k<=NbLines;k++) { 
1779       nbllc++;
1780       const Handle(IntPatch_Line)& LineK = LineConstructor.Line(k);
1781       if (LineK->ArcType() == IntPatch_Analytic) { 
1782         Handle(IntPatch_ALine) alin (Handle(IntPatch_ALine)::DownCast (LineK));
1783         nbvtx=alin->NbVertex();
1784         nbva+=nbvtx;        nba++;
1785         for(v=1;v<=nbvtx;v++) { 
1786           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,alin->Vertex(v));
1787         }
1788       }
1789       else if (LineK->ArcType() == IntPatch_Restriction) {
1790         Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (LineK));
1791         nbvtx=rlin->NbVertex();
1792         nbvr+=nbvtx;        nbr++;
1793         for(v=1;v<=nbvtx;v++) { 
1794           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,rlin->Vertex(v));
1795         }
1796       }
1797       else if (LineK->ArcType() == IntPatch_Walking) {
1798         Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (LineK));
1799         nbvtx=wlin->NbVertex();
1800         nbvw+=nbvtx;        nbw++;
1801         for(v=1;v<=nbvtx;v++) { 
1802           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,wlin->Vertex(v));
1803         }
1804       }
1805       else { 
1806         Handle(IntPatch_GLine) glin (Handle(IntPatch_GLine)::DownCast (LineK));
1807         nbvtx=glin->NbVertex();
1808         nbvg+=nbvtx;        nbg++;
1809         for(v=1;v<=nbvtx;v++) { 
1810           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,glin->Vertex(v));
1811         }
1812       }
1813     }
1814   }
1815   printf("\nDUMP_LC :Lines:%2d WLin:%2d Restr:%2d Ana:%2d Geom:%2d",
1816          nbllc,nbw,nbr,nba,nbg);
1817   printf("\nDUMP_LC :vtx          :%2d     r:%2d    :%2d     :%2d",
1818          nbvw,nbvr,nbva,nbvg);
1819
1820   printf("\n");
1821
1822 #endif 
1823 }