5e02c676212e689303eff308e545ba9ab916c860
[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   if(ts1 == ts2 && ts1 == 1)
914   {
915     const Standard_Boolean RestrictLine = Standard_True;
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     const Standard_Boolean RestrictLine = Standard_True;
950     IntSurf_ListOfPntOn2S ListOfPnts;
951     ListOfPnts.Clear();
952
953     ParamParamPerfom(theS1, theD1, theS2, theD2, TolArc,
954                         TolTang, ListOfPnts, RestrictLine, typs1, typs2);
955   }
956
957   if(!theIsReqToPostWLProc)
958     return;
959
960   for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
961   {
962     Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
963
964     if(aWL.IsNull())
965       continue;
966
967     Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
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 = IntPatch_WLineTool::ComputePurgedWLine(aWL, theS1, theS2, theD1, theD2);
1211
1212     if(aRW.IsNull())
1213       continue;
1214
1215     slin.InsertAfter(i, aRW);
1216     slin.Remove(i);
1217   }
1218 }
1219
1220 //=======================================================================
1221 //function : ParamParamPerfom
1222 //purpose  : 
1223 //=======================================================================
1224 void IntPatch_Intersection::ParamParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
1225                                              const Handle(Adaptor3d_TopolTool)& theD1,
1226                                              const Handle(Adaptor3d_HSurface)&  theS2,
1227                                              const Handle(Adaptor3d_TopolTool)& theD2,
1228                                              const Standard_Real TolArc,
1229                                              const Standard_Real TolTang,
1230                                              IntSurf_ListOfPntOn2S& ListOfPnts,
1231                                              const Standard_Boolean RestrictLine,
1232                                              const GeomAbs_SurfaceType typs1,
1233                                              const GeomAbs_SurfaceType typs2)
1234 {
1235   IntPatch_PrmPrmIntersection interpp;
1236   if(!theD1->DomainIsInfinite() && !theD2->DomainIsInfinite())
1237   {
1238     Standard_Boolean ClearFlag = Standard_True;
1239     if(!ListOfPnts.IsEmpty())
1240     {
1241       interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep, ListOfPnts, RestrictLine);
1242       ClearFlag = Standard_False;
1243     }
1244     interpp.Perform(theS1,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep,ClearFlag);   //double call!!!!!!!
1245   }
1246   else if((theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite()))
1247   {
1248     gp_Pnt pMaxXYZ, pMinXYZ;
1249     if(theD1->DomainIsInfinite())
1250     {
1251       FUN_GetMinMaxXYZPnt( theS2, pMinXYZ, pMaxXYZ );
1252       const Standard_Real MU = Max(Abs(theS2->FirstUParameter()),Abs(theS2->LastUParameter()));
1253       const Standard_Real MV = Max(Abs(theS2->FirstVParameter()),Abs(theS2->LastVParameter()));
1254       const Standard_Real AP = Max(MU, MV);
1255       Handle(Adaptor3d_HSurface) SS;
1256       FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS1, AP, SS);
1257       interpp.Perform(SS,theD1,theS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
1258     }
1259     else
1260     {
1261       FUN_GetMinMaxXYZPnt( theS1, pMinXYZ, pMaxXYZ );
1262       const Standard_Real MU = Max(Abs(theS1->FirstUParameter()),Abs(theS1->LastUParameter()));
1263       const Standard_Real MV = Max(Abs(theS1->FirstVParameter()),Abs(theS1->LastVParameter()));
1264       const Standard_Real AP = Max(MU, MV);
1265       Handle(Adaptor3d_HSurface) SS;
1266       FUN_TrimInfSurf(pMinXYZ, pMaxXYZ, theS2, AP, SS);
1267       interpp.Perform(theS1, theD1, SS, theD2,TolTang, TolArc,myFleche,myUVMaxStep);
1268     }
1269   }//(theD1->DomainIsInfinite()) ^ (theD2->DomainIsInfinite())
1270   else
1271   {
1272     if(typs1 == GeomAbs_OtherSurface || typs2 == GeomAbs_OtherSurface)
1273     {
1274       done = Standard_False;
1275       return;
1276     }
1277
1278     Standard_Boolean IsPLInt = Standard_False;
1279     TColgp_SequenceOfPnt sop;
1280     gp_Vec v;
1281     FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v);
1282
1283     if(IsPLInt)
1284     {
1285       if(sop.Length() > 0)
1286       {
1287         for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
1288         {
1289           gp_Lin lin(sop.Value(ip),gp_Dir(v));
1290           Handle(IntPatch_Line) gl = new IntPatch_GLine(lin,Standard_False);
1291           slin.Append(gl);
1292         }
1293
1294         done = Standard_True;
1295       }
1296       else
1297         done = Standard_False;
1298
1299       return;
1300     }// 'COLLINEAR LINES'
1301     else
1302     {
1303       Handle(Adaptor3d_HSurface) nS1 = theS1;
1304       Handle(Adaptor3d_HSurface) nS2 = theS2;
1305       FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+8,nS1,nS2);
1306       interpp.Perform(nS1,theD1,nS2,theD2,TolTang,TolArc,myFleche,myUVMaxStep);
1307     }// 'NON - COLLINEAR LINES'
1308   }// both domains are infinite
1309
1310   if (interpp.IsDone())
1311   {
1312     done = Standard_True;
1313     tgte = Standard_False;
1314     empt = interpp.IsEmpty();
1315
1316     for(Standard_Integer i = 1; i <= interpp.NbLines(); i++)
1317     {
1318       if(interpp.Line(i)->ArcType() != IntPatch_Walking)
1319         slin.Append(interpp.Line(i));
1320     }
1321
1322     for (Standard_Integer i = 1; i <= interpp.NbLines(); i++)
1323     {
1324       if(interpp.Line(i)->ArcType() == IntPatch_Walking)
1325         slin.Append(interpp.Line(i));
1326     }
1327   }
1328 }
1329
1330 //=======================================================================
1331 ////function : GeomGeomPerfom
1332 //purpose  : 
1333 //=======================================================================
1334 void IntPatch_Intersection::GeomGeomPerfom(const Handle(Adaptor3d_HSurface)& theS1,
1335                                            const Handle(Adaptor3d_TopolTool)& theD1,
1336                                            const Handle(Adaptor3d_HSurface)& theS2,
1337                                            const Handle(Adaptor3d_TopolTool)& theD2,
1338                                            const Standard_Real TolArc,
1339                                            const Standard_Real TolTang,
1340                                            IntSurf_ListOfPntOn2S& ListOfPnts,
1341                                            const Standard_Boolean RestrictLine,
1342                                            const GeomAbs_SurfaceType theTyps1,
1343                                            const GeomAbs_SurfaceType theTyps2,
1344                                            const Standard_Boolean theIsReqToKeepRLine)
1345 {
1346   IntPatch_ImpImpIntersection interii(theS1,theD1,theS2,theD2,
1347                                       myTolArc,myTolTang, theIsReqToKeepRLine);
1348   const Standard_Boolean anIS = interii.IsDone();
1349   if (anIS)
1350   {
1351     done = anIS;
1352     empt = interii.IsEmpty();
1353     if (!empt)
1354     {
1355       tgte = interii.TangentFaces();
1356       if (tgte)
1357         oppo = interii.OppositeFaces();
1358
1359       Standard_Boolean isQuadSet = Standard_False;
1360       IntSurf_Quadric Quad1,Quad2;
1361
1362       for (Standard_Integer i = 1; i <= interii.NbLines(); i++)
1363       {
1364         const Handle(IntPatch_Line)& line = interii.Line(i);
1365         if (line->ArcType() == IntPatch_Analytic)
1366         {
1367           if(!isQuadSet)
1368           {
1369             isQuadSet = Standard_True;
1370             
1371             const GeomAbs_SurfaceType aTyps1 = theS1->GetType();
1372             const GeomAbs_SurfaceType aTyps2 = theS2->GetType();
1373
1374             switch(aTyps1)
1375             {
1376             case GeomAbs_Plane:
1377               Quad1.SetValue(theS1->Plane());
1378               break;
1379
1380             case GeomAbs_Cylinder:
1381               Quad1.SetValue(theS1->Cylinder());
1382               break;
1383
1384             case GeomAbs_Sphere:
1385               Quad1.SetValue(theS1->Sphere());
1386               break;
1387
1388             case GeomAbs_Cone:
1389               Quad1.SetValue(theS1->Cone());
1390               break;
1391
1392             case GeomAbs_Torus:
1393               Quad1.SetValue(theS1->Torus());
1394               break;
1395
1396             default:
1397               isQuadSet = Standard_False;
1398               break;
1399             }
1400
1401             switch(aTyps2)
1402             {
1403             case GeomAbs_Plane:
1404               Quad2.SetValue(theS2->Plane());
1405               break;
1406             case GeomAbs_Cylinder:
1407               Quad2.SetValue(theS2->Cylinder());
1408               break;
1409
1410             case GeomAbs_Sphere:
1411               Quad2.SetValue(theS2->Sphere());
1412               break;
1413
1414             case GeomAbs_Cone:
1415               Quad2.SetValue(theS2->Cone());
1416               break;
1417
1418             case GeomAbs_Torus:
1419               Quad2.SetValue(theS2->Torus());
1420               break;
1421
1422             default:
1423               isQuadSet = Standard_False;
1424               break;
1425             }
1426
1427             if(!isQuadSet)
1428             {
1429               break;
1430             }
1431           }
1432
1433           IntPatch_ALineToWLine AToW(Quad1,Quad2,0.01,0.05,aNbPointsInALine);
1434           Handle(IntPatch_WLine) wlin = 
1435                       AToW.MakeWLine(Handle(IntPatch_ALine)::DownCast(line));
1436           wlin->EnablePurging(Standard_False);
1437           slin.Append(wlin);
1438         }
1439         else
1440           slin.Append(line);
1441       }
1442
1443       if(isQuadSet)
1444       {
1445         Bnd_Box2d aBx1, aBx2;
1446         const Standard_Real aU1F = theS1->FirstUParameter(),
1447                             aU1L = theS1->LastUParameter(),
1448                             aV1F = theS1->FirstVParameter(),
1449                             aV1L = theS1->LastVParameter(),
1450                             aU2F = theS2->FirstUParameter(),
1451                             aU2L = theS2->LastUParameter(),
1452                             aV2F = theS2->FirstVParameter(),
1453                             aV2L = theS2->LastVParameter();
1454         aBx1.Add(gp_Pnt2d(aU1F, aV1F));
1455         aBx1.Add(gp_Pnt2d(aU1L, aV1F));
1456         aBx1.Add(gp_Pnt2d(aU1L, aV1L));
1457         aBx1.Add(gp_Pnt2d(aU1F, aV1L));
1458         aBx2.Add(gp_Pnt2d(aU2F, aV2F));
1459         aBx2.Add(gp_Pnt2d(aU2L, aV2F));
1460         aBx2.Add(gp_Pnt2d(aU2L, aV2L));
1461         aBx2.Add(gp_Pnt2d(aU2F, aV2L));
1462
1463         aBx1.Enlarge(Precision::PConfusion());
1464         aBx2.Enlarge(Precision::PConfusion());
1465
1466         IntPatch_WLineTool::
1467           ExtendTwoWlinesToEachOther(slin, Quad1, Quad2, TolTang,
1468                                      theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
1469                                      theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
1470                                      theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
1471                                      theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
1472                                      aBx1, aBx2);
1473       }
1474
1475       for (Standard_Integer i = 1; i <= interii.NbPnts(); i++)
1476       {
1477         spnt.Append(interii.Point(i));
1478       }
1479     }
1480   }
1481   else
1482     ParamParamPerfom(theS1, theD1, theS2, theD2, 
1483                 TolArc, TolTang, ListOfPnts, RestrictLine, theTyps1, theTyps2);
1484 }
1485
1486 //=======================================================================
1487 //function : GeomParamPerfom
1488 //purpose  : 
1489 //=======================================================================
1490 void IntPatch_Intersection::
1491   GeomParamPerfom(const Handle(Adaptor3d_HSurface)&  theS1,
1492                   const Handle(Adaptor3d_TopolTool)& theD1,
1493                   const Handle(Adaptor3d_HSurface)&  theS2,
1494                   const Handle(Adaptor3d_TopolTool)& theD2,
1495                   const Standard_Boolean isNotAnalitical,
1496                   const GeomAbs_SurfaceType typs1,
1497                   const GeomAbs_SurfaceType typs2)
1498 {
1499   IntPatch_ImpPrmIntersection interip;
1500   if (myIsStartPnt)
1501   {
1502     if (isNotAnalitical/*ts1 == 0*/)
1503       interip.SetStartPoint(myU1Start,myV1Start);
1504     else
1505       interip.SetStartPoint(myU2Start,myV2Start);
1506   }
1507
1508   if(theD1->DomainIsInfinite() && theD2->DomainIsInfinite())
1509   {
1510     Standard_Boolean IsPLInt = Standard_False;
1511     TColgp_SequenceOfPnt sop;
1512     gp_Vec v;
1513     FUN_PL_Intersection(theS1,typs1,theS2,typs2,IsPLInt,sop,v);
1514     
1515     if(IsPLInt)
1516     {
1517       if(sop.Length() > 0)
1518       {
1519         for(Standard_Integer ip = 1; ip <= sop.Length(); ip++)
1520         {
1521           gp_Lin lin(sop.Value(ip),gp_Dir(v));
1522           Handle(IntPatch_Line) gl = new IntPatch_GLine(lin,Standard_False);
1523           slin.Append(gl);
1524         }
1525
1526         done = Standard_True;
1527       }
1528       else
1529         done = Standard_False;
1530
1531       return;
1532     }
1533     else
1534     {
1535       Handle(Adaptor3d_HSurface) nS1 = theS1;
1536       Handle(Adaptor3d_HSurface) nS2 = theS2;
1537       FUN_TrimBothSurf(theS1,typs1,theS2,typs2,1.e+5,nS1,nS2);
1538       interip.Perform(nS1,theD1,nS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep);
1539     }
1540   }
1541   else
1542     interip.Perform(theS1,theD1,theS2,theD2,myTolArc,myTolTang,myFleche,myUVMaxStep);
1543
1544   if (interip.IsDone()) 
1545   {
1546     done = Standard_True;
1547     empt = interip.IsEmpty();
1548
1549     if (!empt)
1550     {
1551       const Standard_Integer aNbLines = interip.NbLines();
1552       for(Standard_Integer i = 1; i <= aNbLines; i++)
1553       {
1554         if(interip.Line(i)->ArcType() != IntPatch_Walking)
1555           slin.Append(interip.Line(i));
1556       }
1557
1558       for(Standard_Integer i = 1; i <= aNbLines; i++)
1559       {
1560         if(interip.Line(i)->ArcType() == IntPatch_Walking)
1561           slin.Append(interip.Line(i));
1562       }
1563
1564       for (Standard_Integer i = 1; i <= interip.NbPnts(); i++)
1565         spnt.Append(interip.Point(i));
1566     }
1567   }
1568 }
1569
1570 //=======================================================================
1571 //function : GeomGeomPerfomTrimSurf
1572 //purpose  : This function returns ready walking-line (which is not need
1573 //            in convertation) as an intersection line between two
1574 //            trimmed surfaces.
1575 //=======================================================================
1576 void IntPatch_Intersection::
1577   GeomGeomPerfomTrimSurf( const Handle(Adaptor3d_HSurface)& theS1,
1578                           const Handle(Adaptor3d_TopolTool)& theD1,
1579                           const Handle(Adaptor3d_HSurface)& theS2,
1580                           const Handle(Adaptor3d_TopolTool)& theD2,
1581                           const Standard_Real theTolArc,
1582                           const Standard_Real theTolTang,
1583                           IntSurf_ListOfPntOn2S& theListOfPnts,
1584                           const Standard_Boolean RestrictLine,
1585                           const GeomAbs_SurfaceType theTyps1,
1586                           const GeomAbs_SurfaceType theTyps2,
1587                           const Standard_Boolean theIsReqToKeepRLine)
1588 {
1589   IntSurf_Quadric Quad1,Quad2;
1590
1591   if((theTyps1 == GeomAbs_Cylinder) && (theTyps2 == GeomAbs_Cylinder))
1592   {
1593     IntPatch_ImpImpIntersection anInt;
1594     anInt.Perform(theS1, theD1, theS2, theD2, myTolArc,
1595                   myTolTang, Standard_True, theIsReqToKeepRLine);
1596
1597     done = anInt.IsDone();
1598
1599     if(done)
1600     {
1601       empt = anInt.IsEmpty();
1602       if (!empt)
1603       {
1604         tgte = anInt.TangentFaces();
1605         if (tgte)
1606           oppo = anInt.OppositeFaces();
1607
1608         const Standard_Integer aNbLin = anInt.NbLines();
1609         const Standard_Integer aNbPts = anInt.NbPnts();
1610
1611         for(Standard_Integer aLID = 1; aLID <= aNbLin; aLID++)
1612         {
1613           const Handle(IntPatch_Line)& aLine = anInt.Line(aLID);
1614           slin.Append(aLine);
1615         }
1616
1617         for(Standard_Integer aPID = 1; aPID <= aNbPts; aPID++)
1618         {
1619           const IntPatch_Point& aPoint = anInt.Point(aPID);
1620           spnt.Append(aPoint);
1621         }
1622
1623         IntPatch_WLineTool::JoinWLines( slin, spnt, theTolTang,
1624                                         theS1->IsUPeriodic()? theS1->UPeriod() : 0.0,
1625                                         theS2->IsUPeriodic()? theS2->UPeriod() : 0.0,
1626                                         theS1->IsVPeriodic()? theS1->VPeriod() : 0.0,
1627                                         theS2->IsVPeriodic()? theS2->VPeriod() : 0.0,
1628                                         theS1->FirstUParameter(),
1629                                         theS1->LastUParameter(),
1630                                         theS1->FirstVParameter(),
1631                                         theS1->LastVParameter(),
1632                                         theS2->FirstUParameter(),
1633                                         theS2->LastUParameter(),
1634                                         theS2->FirstVParameter(),
1635                                         theS2->LastVParameter());
1636       }
1637     }
1638   }
1639   else
1640   {
1641     GeomGeomPerfom(theS1, theD1, theS2, theD2,
1642             theTolArc, theTolTang, theListOfPnts,
1643             RestrictLine, theTyps1, theTyps2, theIsReqToKeepRLine);
1644   }
1645 }
1646
1647
1648 void IntPatch_Intersection::Perform(const Handle(Adaptor3d_HSurface)&  S1,
1649                                     const Handle(Adaptor3d_TopolTool)& D1,
1650                                     const Handle(Adaptor3d_HSurface)&  S2,
1651                                     const Handle(Adaptor3d_TopolTool)& D2,
1652                                     const Standard_Real U1,
1653                                     const Standard_Real V1,
1654                                     const Standard_Real U2,
1655                                     const Standard_Real V2,
1656                                     const Standard_Real TolArc,
1657                                     const Standard_Real TolTang)
1658 {
1659   myTolArc = TolArc;
1660   myTolTang = TolTang;
1661   if(myFleche == 0.0) {
1662 #if DEBUG
1663     //cout<<" -- IntPatch_Intersection::myFleche fixe par defaut a 0.01 --"<<endl;
1664     //cout<<" -- Utiliser la Methode SetTolerances( ... ) "<<endl;
1665 #endif
1666     myFleche = 0.01;
1667   }
1668   if(myUVMaxStep==0.0) {
1669 #if DEBUG
1670     //cout<<" -- IntPatch_Intersection::myUVMaxStep fixe par defaut a 0.01 --"<<endl;
1671     //cout<<" -- Utiliser la Methode SetTolerances( ... ) "<<endl;
1672 #endif
1673     myUVMaxStep = 0.01;
1674   }
1675
1676   done = Standard_False;
1677   spnt.Clear();
1678   slin.Clear();
1679
1680   empt = Standard_True;
1681   tgte = Standard_False;
1682   oppo = Standard_False;
1683
1684   const GeomAbs_SurfaceType typs1 = S1->GetType();
1685   const GeomAbs_SurfaceType typs2 = S2->GetType();
1686   
1687   if(   typs1==GeomAbs_Plane 
1688      || typs1==GeomAbs_Cylinder
1689      || typs1==GeomAbs_Sphere
1690      || typs1==GeomAbs_Cone
1691      || typs2==GeomAbs_Plane 
1692      || typs2==GeomAbs_Cylinder
1693      || typs2==GeomAbs_Sphere
1694      || typs2==GeomAbs_Cone)
1695   {
1696     myIsStartPnt = Standard_True;
1697     myU1Start = U1; myV1Start = V1; myU2Start = U2; myV2Start = V2;
1698     Perform(S1,D1,S2,D2,TolArc,TolTang);
1699     myIsStartPnt = Standard_False;
1700   }
1701   else
1702   {
1703     IntPatch_PrmPrmIntersection interpp;
1704     interpp.Perform(S1,D1,S2,D2,U1,V1,U2,V2,TolTang,TolArc,myFleche,myUVMaxStep);
1705     if (interpp.IsDone())
1706     {
1707       done = Standard_True;
1708       tgte = Standard_False;
1709       empt = interpp.IsEmpty();
1710       const Standard_Integer nblm = interpp.NbLines();
1711       Standard_Integer i = 1;
1712       for (; i<=nblm; i++) slin.Append(interpp.Line(i));
1713     }
1714   }
1715
1716   for(Standard_Integer i = slin.Lower(); i <= slin.Upper(); i++)
1717   {
1718     Handle(IntPatch_WLine) aWL = Handle(IntPatch_WLine)::DownCast(slin.Value(i));
1719
1720     if(aWL.IsNull())
1721       continue;
1722
1723     Handle(IntPatch_WLine) aRW = IntPatch_WLineTool::ComputePurgedWLine(aWL, S1, S2, D1, D2);
1724
1725     if(aRW.IsNull())
1726       continue;
1727
1728     slin.InsertAfter(i, aRW);
1729     slin.Remove(i);
1730   }
1731 }
1732
1733 #ifdef DUMPOFIntPatch_Intersection
1734
1735 void IntPatch_Intersection__MAJ_R(Handle(Adaptor2d_HCurve2d) *R1,
1736                                   Handle(Adaptor2d_HCurve2d) *,
1737                                   int *NR1,
1738                                   int *,
1739                                   Standard_Integer nbR1,
1740                                   Standard_Integer ,
1741                                   const IntPatch_Point& VTX)
1742
1743   
1744   if(VTX.IsOnDomS1()) { 
1745     
1746     //-- long unsigned ptr= *((long unsigned *)(((Handle(Standard_Transient) *)(&(VTX.ArcOnS1())))));
1747     for(Standard_Integer i=0; i<nbR1;i++) { 
1748       if(VTX.ArcOnS1()==R1[i]) { 
1749         NR1[i]++;
1750         printf("\n ******************************");
1751         return;
1752       }
1753     }
1754     printf("\n R Pas trouvee  (IntPatch)\n");
1755     
1756   }
1757 }
1758 #endif
1759
1760 void IntPatch_Intersection::Dump(const Standard_Integer /*Mode*/,
1761                                  const Handle(Adaptor3d_HSurface)&  /*S1*/,
1762                                  const Handle(Adaptor3d_TopolTool)& /*D1*/,
1763                                  const Handle(Adaptor3d_HSurface)&  /*S2*/,
1764                                  const Handle(Adaptor3d_TopolTool)& /*D2*/) const 
1765
1766 #ifdef DUMPOFIntPatch_Intersection
1767   const int MAXR = 200;
1768   //-- ----------------------------------------------------------------------
1769   //--  construction de la liste des restrictions & vertex 
1770   //--
1771   int NR1[MAXR],NR2[MAXR];
1772   Handle(Adaptor2d_HCurve2d) R1[MAXR],R2[MAXR];
1773   Standard_Integer nbR1=0,nbR2=0;
1774   for(D1->Init();D1->More() && nbR1<MAXR; D1->Next()) { 
1775     R1[nbR1]=D1->Value(); 
1776     NR1[nbR1]=0;
1777     nbR1++;
1778   }
1779   for(D2->Init();D2->More() && nbR2<MAXR; D2->Next()) {
1780     R2[nbR2]=D2->Value();
1781     NR2[nbR2]=0;
1782     nbR2++;
1783   }
1784   
1785   printf("\nDUMP_INT:  ----empt:%2ud  tgte:%2ud  oppo:%2ud ---------------------------------",empt,tgte,empt);
1786   Standard_Integer i,nbr1,nbr2,nbgl,nbgc,nbge,nbgp,nbgh,nbl,nbr,nbg,nbw,nba;
1787   nbl=nbr=nbg=nbw=nba=nbgl=nbge=nbr1=nbr2=nbgc=nbgp=nbgh=0;
1788   nbl=NbLines();
1789   for(i=1;i<=nbl;i++) { 
1790     const Handle(IntPatch_Line)& line=Line(i);
1791     const IntPatch_IType IType=line->ArcType();
1792     if(IType == IntPatch_Walking) nbw++;
1793     else     if(IType == IntPatch_Restriction) { 
1794       nbr++;
1795       Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (line));
1796       if(rlin->IsArcOnS1()) nbr1++;
1797       if(rlin->IsArcOnS2()) nbr2++;
1798     }
1799     else     if(IType == IntPatch_Analytic) nba++;
1800     else     { 
1801       nbg++; 
1802       if(IType == IntPatch_Lin) nbgl++;
1803       else if(IType == IntPatch_Circle) nbgc++;
1804       else if(IType == IntPatch_Parabola) nbgp++;
1805       else if(IType == IntPatch_Hyperbola) nbgh++;
1806       else if(IType == IntPatch_Ellipse) nbge++;
1807     }
1808   }
1809   
1810   
1811   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)",
1812          nbl,nbw,nbr,nbr1,nbr2,nba,nbg,nbgl,nbgc,nbge,nbgh,nbgp);
1813   
1814   IntPatch_LineConstructor LineConstructor(2);
1815   
1816   Standard_Integer nbllc=0;
1817   nbw=nbr=nbg=nba=0;
1818   Standard_Integer nbva,nbvw,nbvr,nbvg;
1819   nbva=nbvr=nbvw=nbvg=0;
1820   for (j=1; j<=nbl; j++) {
1821     Standard_Integer v,nbvtx;
1822     const Handle(IntPatch_Line)& intersLinej = Line(j);
1823     Standard_Integer NbLines;
1824     LineConstructor.Perform(SequenceOfLine(),intersLinej,S1,D1,S2,D2,1e-7);
1825     NbLines = LineConstructor.NbLines();
1826     
1827     for(Standard_Integer k=1;k<=NbLines;k++) { 
1828       nbllc++;
1829       const Handle(IntPatch_Line)& LineK = LineConstructor.Line(k);
1830       if (LineK->ArcType() == IntPatch_Analytic) { 
1831         Handle(IntPatch_ALine) alin (Handle(IntPatch_ALine)::DownCast (LineK));
1832         nbvtx=alin->NbVertex();
1833         nbva+=nbvtx;        nba++;
1834         for(v=1;v<=nbvtx;v++) { 
1835           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,alin->Vertex(v));
1836         }
1837       }
1838       else if (LineK->ArcType() == IntPatch_Restriction) {
1839         Handle(IntPatch_RLine) rlin (Handle(IntPatch_RLine)::DownCast (LineK));
1840         nbvtx=rlin->NbVertex();
1841         nbvr+=nbvtx;        nbr++;
1842         for(v=1;v<=nbvtx;v++) { 
1843           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,rlin->Vertex(v));
1844         }
1845       }
1846       else if (LineK->ArcType() == IntPatch_Walking) {
1847         Handle(IntPatch_WLine) wlin (Handle(IntPatch_WLine)::DownCast (LineK));
1848         nbvtx=wlin->NbVertex();
1849         nbvw+=nbvtx;        nbw++;
1850         for(v=1;v<=nbvtx;v++) { 
1851           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,wlin->Vertex(v));
1852         }
1853       }
1854       else { 
1855         Handle(IntPatch_GLine) glin (Handle(IntPatch_GLine)::DownCast (LineK));
1856         nbvtx=glin->NbVertex();
1857         nbvg+=nbvtx;        nbg++;
1858         for(v=1;v<=nbvtx;v++) { 
1859           IntPatch_Intersection__MAJ_R(R1,R2,NR1,NR2,nbR1,nbR2,glin->Vertex(v));
1860         }
1861       }
1862     }
1863   }
1864   printf("\nDUMP_LC :Lines:%2d WLin:%2d Restr:%2d Ana:%2d Geom:%2d",
1865          nbllc,nbw,nbr,nba,nbg);
1866   printf("\nDUMP_LC :vtx          :%2d     r:%2d    :%2d     :%2d",
1867          nbvw,nbvr,nbva,nbvg);
1868
1869   printf("\n");
1870
1871 #endif 
1872 }