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