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