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