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