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