d1949de824e539926c0208c807ec7ade4ba7146d
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_5.gxx
1 // Created on: 1992-05-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #include <gce_MakeLin.hxx>
18
19 //=======================================================================
20 //function : IntCoCo
21 //purpose  : 
22 //=======================================================================
23 Standard_Boolean IntCoCo(const IntSurf_Quadric& Quad1,
24                          const IntSurf_Quadric& Quad2,
25                          const Standard_Real Tol,
26                          Standard_Boolean& Empty,
27                          Standard_Boolean& Same,
28                          Standard_Boolean& Multpoint,
29                          IntPatch_SequenceOfLine& slin,
30                          IntPatch_SequenceOfPoint& spnt)
31
32 {
33   Standard_Integer i, NbSol;
34   Standard_Real U1,V1,U2,V2;
35   IntSurf_TypeTrans trans1,trans2;
36   IntAna_ResultType typint;
37   //
38   gp_Cone Co1(Quad1.Cone());
39   gp_Cone Co2(Quad2.Cone());
40   //
41   IntAna_QuadQuadGeo inter(Co1,Co2,Tol);
42   if (!inter.IsDone()) {
43     return Standard_False;
44   }
45   //
46   typint = inter.TypeInter();
47   NbSol = inter.NbSolutions();
48   Empty = Standard_False;
49   Same  = Standard_False;
50
51   switch (typint) {
52
53   case IntAna_Empty :
54     {
55       Empty = Standard_True;
56     }
57     break;
58
59   case IntAna_Same:
60     {
61         Same  = Standard_True;
62     }
63     break;
64
65     //modified by NIZNHY-PKV Wed Nov 30 12:56:06 2005f
66   case IntAna_Line :{
67     Standard_Real para, aDot;
68     gp_Pnt aPApex1, aPApex2, ptbid;
69     gp_Lin linsol;
70     gp_Vec NormC1,NormC2;
71     IntPatch_Point aPtsol;
72     Handle(IntPatch_GLine) glig;
73     //
74     aPApex1=Co1.Apex();
75     aPApex2=Co2.Apex();
76     //
77     if (NbSol==1) {
78       IntSurf_Situation situC1, situC2;
79       //
80       linsol = inter.Line(1);
81       para =ElCLib::Parameter(linsol, aPApex1);
82       ptbid=ElCLib::Value(para+5., linsol);
83       Quad1.Parameters(aPApex1, U1, V1);
84       Quad2.Parameters(aPApex1, U2, V2);
85       //
86       aPtsol.SetValue(aPApex1, Tol, Standard_False);
87       aPtsol.SetParameters(U1, V1, U2, V2);
88       aPtsol.SetParameter(para);
89       //
90       NormC1=Quad1.Normale(ptbid);
91       NormC2=Quad2.Normale(ptbid);
92       aDot=NormC1.Dot(NormC2);
93       if (aDot<0.) {
94         situC1=IntSurf_Outside;
95         situC2=IntSurf_Outside;
96       }
97       else {
98         Standard_Real aR1, aR2;
99         gp_Lin aLAx1(aPApex1, Co1.Axis().Direction());
100         gp_Lin aLAx2(aPApex2, Co2.Axis().Direction());
101         //
102         aR1=aLAx1.Distance(ptbid);
103         aR2=aLAx2.Distance(ptbid);
104         //
105         situC1=IntSurf_Inside;
106         situC2=IntSurf_Outside;
107         if (aR1>aR2) {                                  // Intersection line parametrizes from Apex1 to Apex2,
108           situC1=IntSurf_Outside;               // So the distance betwee ptbid and aLAx1 is greater than the 
109           situC2=IntSurf_Inside;                // distance between ptbid and aLAx2 and in that case Cone2 
110                                                                         // is inside Cone 1
111         }
112       }
113       // 1
114       glig=new IntPatch_GLine(linsol, Standard_True, situC1, situC2);
115       glig->AddVertex(aPtsol);
116       glig->SetFirstPoint(1);
117       slin.Append(glig);
118       // 2
119       linsol.SetDirection(linsol.Direction().Reversed());
120       para =ElCLib::Parameter(linsol, aPApex1);
121       aPtsol.SetParameter(para);
122       
123       glig = new IntPatch_GLine(linsol, Standard_True, situC2, situC1);
124       glig->AddVertex(aPtsol);
125       glig->SetFirstPoint(1);
126       slin.Append(glig);
127     } // if (NbSol==1) {
128     //////////////////////
129     else if (NbSol==2) {
130       //
131       for (i=1; i<=2; ++i) {
132         linsol = inter.Line(i);
133         para =ElCLib::Parameter(linsol, aPApex1);
134         ptbid=ElCLib::Value(para+5., linsol);
135         Quad1.Parameters(aPApex1, U1, V1);
136         Quad2.Parameters(aPApex1, U2, V2);
137         //
138         trans1 = IntSurf_In;
139         trans2 = IntSurf_Out;
140         if (linsol.Direction().
141             DotCross(Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
142           trans1 = IntSurf_Out;
143           trans2 = IntSurf_In;
144         }
145         //
146         Multpoint = Standard_True;
147         // 1,3
148         aPtsol.SetValue(aPApex1, Tol, Standard_False);
149         aPtsol.SetParameters(U1,V1,U2,V2);
150         aPtsol.SetParameter(para);
151         aPtsol.SetMultiple(Standard_True);
152         
153         glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
154         glig->AddVertex(aPtsol);
155         glig->SetFirstPoint(1);
156         slin.Append(glig);
157         // 2,4
158         linsol.SetDirection(linsol.Direction().Reversed());
159         para = ElCLib::Parameter(linsol, aPApex1);
160         aPtsol.SetParameter(para);
161         glig = new IntPatch_GLine(linsol, Standard_False, trans1, trans2);
162         glig->AddVertex(aPtsol);
163         glig->SetFirstPoint(1);
164         slin.Append(glig);
165         //
166       } //for (i=1; i<=2; ++i) 
167     } //else if (NbSol==2)
168   }
169     break;
170     //modified by NIZNHY-PKV Wed Nov 30 12:56:10 2005t
171   
172   case IntAna_Point : {
173     gp_Pnt ptcontact;
174     gp_Pnt apex1(Co1.Apex());
175     gp_Pnt apex2(Co2.Apex());
176     Standard_Real param1,param2;
177     Standard_Real paramapex1   = ElCLib::LineParameter(Co1.Axis(),apex1);
178     Standard_Real paramapex2   = ElCLib::LineParameter(Co2.Axis(),apex2);
179     for (i=1; i <= NbSol; i++) {
180       ptcontact = inter.Point(i);
181       param1 = ElCLib::LineParameter(Co1.Axis(),ptcontact);
182       param2 = ElCLib::LineParameter(Co2.Axis(),ptcontact);
183       
184       Quad1.Parameters(ptcontact,U1,V1);
185       Quad2.Parameters(ptcontact,U2,V2);
186       
187       if (apex1.Distance(ptcontact) <= Tol &&
188           apex2.Distance(ptcontact) <= Tol) {
189         IntPatch_Point ptsol;
190         ptsol.SetValue(ptcontact,Tol,Standard_False);
191         ptsol.SetParameters(U1,V1,U2,V2);
192         spnt.Append(ptsol);
193       }
194       else if (param1 >= paramapex1 && param2 >= paramapex2) {
195         IntPatch_Point ptsol;
196         ptsol.SetValue(ptcontact,Tol,Standard_True);
197         ptsol.SetParameters(U1,V1,U2,V2);
198         spnt.Append(ptsol);
199       }
200     }
201   }
202     break;
203
204   case IntAna_Circle:
205     {
206       Standard_Real para;
207       IntPatch_Point aPtsol;
208       gp_Vec Tgt;
209       gp_Pnt ptref;
210       for (i = 1; i <= NbSol; i++) {
211         gp_Circ cirsol = inter.Circle(i);
212         ElCLib::D1(0.,cirsol,ptref,Tgt);
213         Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
214         if(qwe> 0.00000001) {
215           trans1 = IntSurf_Out;
216           trans2 = IntSurf_In;
217         }
218         else if(qwe<-0.00000001){
219           trans1 = IntSurf_In;
220           trans2 = IntSurf_Out;
221         }
222         else { 
223           trans1=trans2=IntSurf_Undecided; 
224         }
225         Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
226         if(inter.HasCommonGen()) {
227           const gp_Pnt& aPChar = inter.PChar();
228           Quad1.Parameters(aPChar, U1, V1);
229           Quad2.Parameters(aPChar, U2, V2);
230           aPtsol.SetValue(aPChar, Tol, Standard_False);
231           aPtsol.SetParameters(U1, V1, U2, V2);
232           para = ElCLib::Parameter(cirsol, aPChar);
233           aPtsol.SetParameter(0.);
234           glig->AddVertex(aPtsol);
235         }
236         slin.Append(glig);
237       }
238     }
239     break;
240
241
242   case IntAna_Ellipse:
243     {
244       Standard_Real para;
245       IntPatch_Point aPtsol;
246       gp_Elips elipsol = inter.Ellipse(1);
247       
248       gp_Vec Tgt;
249       gp_Pnt ptref;
250       ElCLib::D1(0.,elipsol,ptref,Tgt);
251       
252       Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
253       if(qwe> 0.00000001) {
254         trans1 = IntSurf_Out;
255         trans2 = IntSurf_In;
256       }
257       else if(qwe<-0.00000001) {
258         trans1 = IntSurf_In;
259         trans2 = IntSurf_Out;
260       }
261       else { 
262         trans1=trans2=IntSurf_Undecided;
263       }
264       Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
265       if(inter.HasCommonGen()) {
266         const gp_Pnt& aPChar = inter.PChar();
267         Quad1.Parameters(aPChar, U1, V1);
268         Quad2.Parameters(aPChar, U2, V2);
269         aPtsol.SetValue(aPChar, Tol, Standard_False);
270         aPtsol.SetParameters(U1, V1, U2, V2);
271         para = ElCLib::Parameter(elipsol, aPChar);
272         aPtsol.SetParameter(0.);
273         glig->AddVertex(aPtsol);
274       }
275       slin.Append(glig);
276       
277     }
278     break;
279
280
281   case IntAna_Hyperbola:
282     {
283       Standard_Real para;
284       IntPatch_Point aPtsol;
285       gp_Vec Tgt;
286       gp_Pnt ptref;
287       for(i=1; i<=2; i++) { 
288         gp_Hypr hyprsol = inter.Hyperbola(i);
289         ElCLib::D1(0.,hyprsol,ptref,Tgt);
290         Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
291         if(qwe> 0.00000001) {
292           trans1 = IntSurf_Out;
293           trans2 = IntSurf_In;
294         }
295         else if(qwe<-0.00000001){
296           trans1 = IntSurf_In;
297           trans2 = IntSurf_Out;
298         }
299         else { 
300           trans1=trans2=IntSurf_Undecided; 
301         }
302         Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol,Standard_False,trans1,trans2);
303         if(inter.HasCommonGen()) {
304           const gp_Pnt& aPChar = inter.PChar();
305           Quad1.Parameters(aPChar, U1, V1);
306           Quad2.Parameters(aPChar, U2, V2);
307           aPtsol.SetValue(aPChar, Tol, Standard_False);
308           aPtsol.SetParameters(U1, V1, U2, V2);
309           para = ElCLib::Parameter(hyprsol, aPChar);
310           aPtsol.SetParameter(0.);
311           glig->AddVertex(aPtsol);
312         }
313         slin.Append(glig);
314       }
315     }
316     break;
317     
318   case IntAna_Parabola:
319     {
320       Standard_Real para;
321       IntPatch_Point aPtsol;
322       gp_Parab parabsol = inter.Parabola(1);
323       
324       gp_Vec Tgtorig(parabsol.YAxis().Direction());
325       Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()),
326                                                Quad1.Normale(parabsol.Location()));
327       if (ptran >0.00000001) {
328         trans1 = IntSurf_Out;
329         trans2 = IntSurf_In;
330       }
331       else if (ptran <-0.00000001) {
332         trans1 = IntSurf_In;
333         trans2 = IntSurf_Out;
334       }
335       else { 
336         trans1=trans2=IntSurf_Undecided; 
337       }
338
339       Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol,Standard_False,trans1,trans2);
340       if(inter.HasCommonGen()) {
341         const gp_Pnt& aPChar = inter.PChar();
342         Quad1.Parameters(aPChar, U1, V1);
343         Quad2.Parameters(aPChar, U2, V2);
344         aPtsol.SetValue(aPChar, Tol, Standard_False);
345         aPtsol.SetParameters(U1, V1, U2, V2);
346         para = ElCLib::Parameter(parabsol, aPChar);
347         aPtsol.SetParameter(0.);
348         glig->AddVertex(aPtsol);
349       }
350       slin.Append(glig);
351     }
352     break;
353     
354     
355   case IntAna_NoGeometricSolution:
356     {
357       gp_Pnt psol;
358       IntAna_IntQuadQuad anaint(Co1,Co2,Tol);
359       if (!anaint.IsDone()) {
360         return Standard_False;
361       }
362
363       if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
364         Empty = Standard_True;
365       }
366       else {
367         NbSol = anaint.NbPnt();
368         for (i = 1; i <= NbSol; i++) {
369           psol = anaint.Point(i);
370           Quad1.Parameters(psol,U1,V1);
371           Quad2.Parameters(psol,U2,V2);
372           IntPatch_Point ptsol;
373           ptsol.SetValue(psol,Tol,Standard_True);
374           ptsol.SetParameters(U1,V1,U2,V2);
375           spnt.Append(ptsol);
376         }
377
378         gp_Pnt ptvalid, ptf, ptl;
379         gp_Vec tgvalid;
380
381         Standard_Real first,last,para;
382         Standard_Boolean tgfound,firstp,lastp,kept;
383         Standard_Integer kount;
384         
385         NbSol = anaint.NbCurve();
386         for (i = 1; i <= NbSol; i++) {
387           Handle(IntPatch_ALine) alig;
388           kept = Standard_False;
389           IntAna_Curve curvsol = anaint.Curve(i);
390           curvsol.Domain(first,last);
391           firstp = !curvsol.IsFirstOpen();
392           lastp  = !curvsol.IsLastOpen();
393           if (firstp) {
394             ptf = curvsol.Value(first);
395           }
396           if (lastp) {
397             ptl = curvsol.Value(last);
398           }
399           para = last;
400           kount = 1;
401           tgfound = Standard_False;
402           
403           while (!tgfound) {
404             para = (1.123*first + para)/2.123;
405             tgfound = curvsol.D1u(para,ptvalid,tgvalid);
406             if(tgvalid.SquareMagnitude() < 1e-14) { 
407               //-- on se trouve ds un cas ou les normales n'auront pas de sens
408               tgfound = Standard_False; 
409             } 
410               
411             if (!tgfound) {
412               kount ++;
413               tgfound = kount > 5;
414             }
415           }
416           if (kount <= 5) {
417             Standard_Real qwe= tgvalid.DotCross(Quad2.Normale(ptvalid),
418                                                 Quad1.Normale(ptvalid));
419             if(qwe > 0.000000001) {
420               trans1 = IntSurf_Out;
421               trans2 = IntSurf_In;
422             }
423             else if(qwe < -0.000000001) {
424               trans1 = IntSurf_In;
425               trans2 = IntSurf_Out;
426             }
427             else { 
428               trans1=trans2=IntSurf_Undecided;
429             }
430             alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
431             kept = Standard_True;
432           }
433           else {
434             ptvalid = curvsol.Value(para);
435             alig = new IntPatch_ALine(curvsol,Standard_False);
436             kept = Standard_True;
437             //-- cout << "Transition indeterminee" << endl;
438           }
439           if (kept) {
440             Standard_Boolean Nfirstp = !firstp;
441             Standard_Boolean Nlastp  = !lastp;
442             ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
443                           Nlastp,ptl,last,Multpoint,Tol);
444             slin.Append(alig);
445           }
446         }
447       }
448     }
449     break;
450     
451   default:
452     {
453       return Standard_False;
454     }
455   }
456
457   //When two cones have common generatrix passing trough apexes
458   //it is necessary to add it is solution
459   if(inter.HasCommonGen()) {
460     Standard_Real para;
461     IntPatch_Point aPtsol;
462     gp_Pnt aPApex1, aPApex2;
463     aPApex1=Co1.Apex();
464     aPApex2=Co2.Apex();
465     //common generatrix of cones
466     gce_MakeLin aMkLin(aPApex1, aPApex2);
467     const gp_Lin& linsol = aMkLin.Value();
468     Handle(IntPatch_GLine) glig = 
469       new IntPatch_GLine(linsol,Standard_True,IntSurf_Undecided,IntSurf_Undecided);
470     
471     const gp_Pnt& aPChar = inter.PChar();
472     Quad1.Parameters(aPChar, U1, V1);
473     Quad2.Parameters(aPChar, U2, V2);
474     aPtsol.SetValue(aPChar, Tol, Standard_False);
475     aPtsol.SetParameters(U1, V1, U2, V2);
476     para = ElCLib::Parameter(linsol, aPChar);
477     aPtsol.SetParameter(para);
478     glig->AddVertex(aPtsol);
479
480     slin.Append(glig);
481
482   }    
483
484   return Standard_True;
485 }
486 //=======================================================================
487 //function : IntCoSp
488 //purpose  : 
489 //=======================================================================
490 Standard_Boolean IntCoSp(const IntSurf_Quadric& Quad1,
491                          const IntSurf_Quadric& Quad2,
492                          const Standard_Real Tol,
493                          const Standard_Boolean Reversed,
494                          Standard_Boolean& Empty,
495                          Standard_Boolean& Multpoint,
496                          IntPatch_SequenceOfLine& slin,
497                          IntPatch_SequenceOfPoint& spnt)
498
499 {
500
501   Standard_Integer i;
502
503   IntSurf_TypeTrans trans1,trans2;
504   IntAna_ResultType typint;
505
506   gp_Sphere Sp;
507   gp_Cone   Co;
508   Standard_Real U1,V1,U2,V2;
509
510   if (!Reversed) {
511     Co = Quad1.Cone();
512     Sp = Quad2.Sphere();
513   }
514   else {
515     Co = Quad2.Cone();
516     Sp = Quad1.Sphere();
517   }
518   IntAna_QuadQuadGeo inter(Sp,Co,Tol);
519
520   if (!inter.IsDone()) {return Standard_False;}
521
522   typint = inter.TypeInter();
523   Standard_Integer NbSol = inter.NbSolutions();
524   Empty = Standard_False;
525
526   switch (typint) {
527
528   case IntAna_Empty :
529     {
530       Empty = Standard_True;
531     }
532     break;
533
534   case IntAna_Point :
535     {
536       gp_Pnt ptcontact;
537       gp_Pnt apex(Co.Apex());
538       Standard_Real param;
539       Standard_Real paramapex   = ElCLib::LineParameter(Co.Axis(),apex);
540       for (i=1; i <= NbSol; i++) {
541         ptcontact = inter.Point(i);
542         param = ElCLib::LineParameter(Co.Axis(),ptcontact);
543         Quad1.Parameters(ptcontact,U1,V1);
544         Quad2.Parameters(ptcontact,U2,V2);
545
546         if (apex.Distance(ptcontact) <= Tol) {
547           IntPatch_Point ptsol;
548           ptsol.SetValue(ptcontact,Tol,Standard_False);
549           ptsol.SetParameters(U1,V1,U2,V2);
550           spnt.Append(ptsol);
551         }
552         else if (param >= paramapex) {
553           IntPatch_Point ptsol;
554           ptsol.SetValue(ptcontact,Tol,Standard_True);
555           ptsol.SetParameters(U1,V1,U2,V2);
556           spnt.Append(ptsol);
557         }
558       }
559     }
560     break;
561
562   case IntAna_Circle:
563     {
564       gp_Vec Tgt;
565       gp_Pnt ptref;
566
567       for (i=1; i<=NbSol; i++) {
568         gp_Circ cirsol = inter.Circle(i);
569         //-- param = ElCLib::LineParameter(Co.Axis(),
570         //--                          cirsol.Location());
571         //-- if (param >= paramapex) {
572         
573         ElCLib::D1(0.,cirsol,ptref,Tgt);
574         Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
575                                          Quad1.Normale(ptref));
576         if(qwe> 0.00000001) {
577           trans1 = IntSurf_Out;
578           trans2 = IntSurf_In;
579         }
580         else if(qwe< -0.00000001) {
581           trans1 = IntSurf_In;
582           trans2 = IntSurf_Out;
583         }
584         else { 
585           trans1=trans2=IntSurf_Undecided; 
586         }
587         Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
588         slin.Append(glig);
589         //-- }
590       }
591     }
592     break;
593
594   case IntAna_PointAndCircle:
595     {
596       gp_Vec Tgt;
597       gp_Pnt ptref;
598       gp_Pnt apex(Co.Apex());
599       Standard_Real param;
600       Standard_Real paramapex   = ElCLib::LineParameter(Co.Axis(),apex);
601
602       // le point est necessairement l apex
603       Quad1.Parameters(apex,U1,V1);
604       Quad2.Parameters(apex,U2,V2);
605       IntPatch_Point ptsol;
606       ptsol.SetValue(apex,Tol,Standard_False);
607       ptsol.SetParameters(U1,V1,U2,V2);
608       spnt.Append(ptsol);
609
610       gp_Circ cirsol = inter.Circle(1);
611       param = ElCLib::LineParameter(Co.Axis(),
612                                     cirsol.Location());
613       if (param >= paramapex) {
614         
615         ElCLib::D1(0.,cirsol,ptref,Tgt);
616         Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),
617                                          Quad1.Normale(ptref));
618         if(qwe> 0.000000001) {
619           trans1 = IntSurf_Out;
620           trans2 = IntSurf_In;
621         }
622         else if(qwe< -0.000000001){
623           trans1 = IntSurf_In;
624           trans2 = IntSurf_Out;
625         }
626         else { 
627           trans1=trans2=IntSurf_Undecided;
628         }
629         Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
630         slin.Append(glig);
631       }
632     }
633     break;
634
635   case IntAna_NoGeometricSolution:
636     {
637       gp_Pnt psol;
638       IntAna_IntQuadQuad anaint(Co,Sp,Tol);
639       if (!anaint.IsDone()) {
640         return Standard_False;
641       }
642       
643       if (anaint.NbPnt()==0 && anaint.NbCurve()==0) {
644         Empty = Standard_True;
645       }
646       else {
647         NbSol = anaint.NbPnt();
648         for (i = 1; i <= NbSol; i++) {
649           psol = anaint.Point(i);
650           Quad1.Parameters(psol,U1,V1);
651           Quad2.Parameters(psol,U2,V2);
652           IntPatch_Point ptsol;
653           ptsol.SetValue(psol,Tol,Standard_True);
654           ptsol.SetParameters(U1,V1,U2,V2);
655           spnt.Append(ptsol);
656         }
657
658         gp_Pnt ptvalid, ptf, ptl;
659         gp_Vec tgvalid;
660         Standard_Real first,last,para;
661         Standard_Boolean tgfound,firstp,lastp,kept;
662         Standard_Integer kount;
663         
664         NbSol = anaint.NbCurve();
665         for (i = 1; i <= NbSol; i++) {
666           Handle(IntPatch_ALine) alig;
667           kept = Standard_False;
668           IntAna_Curve curvsol = anaint.Curve(i);
669           curvsol.Domain(first,last);
670           firstp = !curvsol.IsFirstOpen();
671           lastp  = !curvsol.IsLastOpen();
672           if (firstp) {
673             ptf = curvsol.Value(first);
674           }
675           if (lastp) {
676             ptl = curvsol.Value(last);
677           }
678           para = last;
679           kount = 1;
680           tgfound = Standard_False;
681           
682           while (!tgfound) {
683             para = (1.123*first + para)/2.123;
684             tgfound = curvsol.D1u(para,ptvalid,tgvalid);
685             if (!tgfound) {
686               kount ++;
687               tgfound = kount > 5;
688             }
689           }
690           if (kount <= 5) {
691             para = ElCLib::LineParameter(Co.Axis(),ptvalid);
692             Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
693                                                  Quad1.Normale(ptvalid));
694             if(qwe> 0.000000001) {
695               trans1 = IntSurf_Out;
696               trans2 = IntSurf_In;
697             }
698             else if(qwe<-0.000000001) {
699               trans1 = IntSurf_In;
700               trans2 = IntSurf_Out;
701             }
702             else { 
703               trans1=trans2=IntSurf_Undecided; 
704             }
705             alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
706             kept = Standard_True;
707           }
708           else {
709             ptvalid = curvsol.Value(para);
710             para = ElCLib::LineParameter(Co.Axis(),ptvalid);
711             alig = new IntPatch_ALine(curvsol,Standard_False);
712             kept = Standard_True;
713             //-- cout << "Transition indeterminee" << endl;
714           }
715           if (kept) {
716             Standard_Boolean Nfirstp = !firstp;
717             Standard_Boolean Nlastp  = !lastp;
718             ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
719                           Nlastp,ptl,last,Multpoint,Tol);
720             slin.Append(alig);
721           }
722         }
723       }
724     }
725     break;
726
727   default:
728     {
729       return Standard_False;
730     }
731   }
732
733   return Standard_True;
734 }
735 //=======================================================================
736 //function : IntSpSp
737 //purpose  : 
738 //=======================================================================
739 Standard_Boolean IntSpSp(const IntSurf_Quadric& Quad1,
740                          const IntSurf_Quadric& Quad2,
741                          const Standard_Real Tol,
742                          Standard_Boolean& Empty,
743                          Standard_Boolean& Same,
744                          IntPatch_SequenceOfLine& slin,
745                          IntPatch_SequenceOfPoint& spnt)
746
747 // Traitement du cas Sphere/Sphere
748
749 {
750   IntSurf_TypeTrans trans1,trans2;
751   IntAna_ResultType typint;
752   gp_Sphere sph1(Quad1.Sphere());
753   gp_Sphere sph2(Quad2.Sphere());
754
755   IntAna_QuadQuadGeo inter(sph1,sph2,Tol);
756   if (!inter.IsDone()) {return Standard_False;}
757
758   typint = inter.TypeInter();
759   Empty  = Standard_False;
760   Same   = Standard_False;
761
762   switch (typint) {
763
764   case IntAna_Empty :
765     {
766       Empty = Standard_True;
767     }
768     break;
769
770   case IntAna_Same:
771     {
772       Same  = Standard_True;
773     }
774     break;
775
776   case IntAna_Point:
777     {
778       gp_Pnt psol(inter.Point(1));
779       Standard_Real U1,V1,U2,V2;
780       Quad1.Parameters(psol,U1,V1);
781       Quad2.Parameters(psol,U2,V2);
782       IntPatch_Point ptsol;
783       ptsol.SetValue(psol,Tol,Standard_True);
784       ptsol.SetParameters(U1,V1,U2,V2);
785       spnt.Append(ptsol);
786     }
787     break;
788     
789   case IntAna_Circle:
790     {
791       gp_Circ cirsol = inter.Circle(1);
792       gp_Pnt ptref;
793       gp_Vec Tgt;
794       ElCLib::D1(0.,cirsol,ptref,Tgt);
795
796       Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
797       if(qwe>0.00000001) {
798         trans1 = IntSurf_Out;
799         trans2 = IntSurf_In;
800       }
801       else  if(qwe<-0.00000001) {
802         trans1 = IntSurf_In;
803         trans2 = IntSurf_Out;
804       }
805       else { 
806         trans1=trans2=IntSurf_Undecided; 
807       }
808       Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
809       slin.Append(glig);
810     }
811     break;
812     
813   default:
814     {
815       return Standard_False;  // on ne doit pas passer ici
816     }
817   }
818   return Standard_True;
819 }