bedbf7f6d90f1c3c9f9e0cbc3044102d9e831a4d
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_4.gxx
1 // File:      IntPatch_ImpImpIntersection_4.gxx
2 // Created:   Thu May  7 08:47:45 1992
3 // Author:    Jacques GOUSSARD
4 // Copyright: OPEN CASCADE 1992
5
6 #include <IntAna_ListOfCurve.hxx>
7 #include <IntAna_ListIteratorOfListOfCurve.hxx>
8
9 static 
10   Standard_Boolean ExploreCurve(const gp_Cylinder& aCy,
11                                 const gp_Cone& aCo,
12                                 IntAna_Curve& aC,
13                                 const Standard_Real aTol,
14                                 IntAna_ListOfCurve& aLC);
15 static
16   Standard_Boolean IsToReverse(const gp_Cylinder& Cy1,
17                                const gp_Cylinder& Cy2,
18                                const Standard_Real Tol);
19
20 //=======================================================================
21 //function : ProcessBounds
22 //purpose  : 
23 //=======================================================================
24 void ProcessBounds(const Handle(IntPatch_ALine)& alig,          //-- ligne courante
25                    const IntPatch_SequenceOfLine& slin,
26                    const IntSurf_Quadric& Quad1,
27                    const IntSurf_Quadric& Quad2,
28                    Standard_Boolean& procf,
29                    const gp_Pnt& ptf,                     //-- Debut Ligne Courante
30                    const Standard_Real first,             //-- Paramf
31                    Standard_Boolean& procl,
32                    const gp_Pnt& ptl,                     //-- Fin Ligne courante
33                    const Standard_Real last,              //-- Paraml
34                    Standard_Boolean& Multpoint,
35                    const Standard_Real Tol)
36 {  
37   Standard_Integer j,k;
38   Standard_Real U1,V1,U2,V2;
39   IntPatch_Point ptsol;
40   Standard_Real d;
41   
42   if (procf && procl) {
43     j = slin.Length() + 1;
44   }
45   else {
46     j = 1;
47   }
48
49
50   //-- On prend les lignes deja enregistrees
51
52   while (j <= slin.Length()) {  
53     if(slin.Value(j)->ArcType() == IntPatch_Analytic) { 
54       const Handle(IntPatch_ALine)& aligold = *((Handle(IntPatch_ALine)*)&slin.Value(j));
55       k = 1;
56
57       //-- On prend les vertex des lignes deja enregistrees
58
59       while (k <= aligold->NbVertex()) {
60         ptsol = aligold->Vertex(k);            
61         if (!procf) {
62           d=ptf.Distance(ptsol.Value());
63           if (d <= Tol) {
64             if (!ptsol.IsMultiple()) {
65               //-- le point ptsol (de aligold) est declare multiple sur aligold
66               Multpoint = Standard_True;
67               ptsol.SetMultiple(Standard_True);
68               aligold->Replace(k,ptsol);
69             }
70             ptsol.SetParameter(first);
71             alig->AddVertex(ptsol);
72             alig->SetFirstPoint(alig->NbVertex());
73             procf = Standard_True;
74
75             //-- On restore le point avec son parametre sur aligold
76             ptsol = aligold->Vertex(k); 
77                                         
78           }
79         }
80         if (!procl) {
81           if (ptl.Distance(ptsol.Value()) <= Tol) {
82             if (!ptsol.IsMultiple()) {
83               Multpoint = Standard_True;
84               ptsol.SetMultiple(Standard_True);
85               aligold->Replace(k,ptsol);
86             }
87             ptsol.SetParameter(last);
88             alig->AddVertex(ptsol);
89             alig->SetLastPoint(alig->NbVertex());
90             procl = Standard_True;
91
92             //-- On restore le point avec son parametre sur aligold
93             ptsol = aligold->Vertex(k); 
94              
95           }
96         }
97         if (procf && procl) {
98           k = aligold->NbVertex()+1;
99         }
100         else {
101           k = k+1;
102         }
103       }
104       if (procf && procl) {
105         j = slin.Length()+1;
106       }
107       else {
108         j = j+1;
109       }
110     }
111   }
112   if (!procf && !procl) {
113     Quad1.Parameters(ptf,U1,V1);
114     Quad2.Parameters(ptf,U2,V2);
115     ptsol.SetValue(ptf,Tol,Standard_False);
116     ptsol.SetParameters(U1,V1,U2,V2);
117     ptsol.SetParameter(first);
118     if (ptf.Distance(ptl) <= Tol) {
119       ptsol.SetMultiple(Standard_True); // a voir
120       Multpoint = Standard_True;        // a voir de meme
121       alig->AddVertex(ptsol);
122       alig->SetFirstPoint(alig->NbVertex());
123       
124       ptsol.SetParameter(last);
125       alig->AddVertex(ptsol);
126       alig->SetLastPoint(alig->NbVertex());
127     }
128     else { 
129       alig->AddVertex(ptsol);
130       alig->SetFirstPoint(alig->NbVertex());
131       Quad1.Parameters(ptl,U1,V1);
132       Quad2.Parameters(ptl,U2,V2);
133       ptsol.SetValue(ptl,Tol,Standard_False);
134       ptsol.SetParameters(U1,V1,U2,V2);
135       ptsol.SetParameter(last);
136       alig->AddVertex(ptsol);
137       alig->SetLastPoint(alig->NbVertex());
138     }
139   }
140   else if (!procf) {
141     Quad1.Parameters(ptf,U1,V1);
142     Quad2.Parameters(ptf,U2,V2);
143     ptsol.SetValue(ptf,Tol,Standard_False);
144     ptsol.SetParameters(U1,V1,U2,V2);
145     ptsol.SetParameter(first);
146     alig->AddVertex(ptsol);
147     alig->SetFirstPoint(alig->NbVertex());
148   }
149   else if (!procl) {
150     Quad1.Parameters(ptl,U1,V1);
151     Quad2.Parameters(ptl,U2,V2);
152     ptsol.SetValue(ptl,Tol,Standard_False);
153     ptsol.SetParameters(U1,V1,U2,V2);
154     ptsol.SetParameter(last);
155     alig->AddVertex(ptsol);
156     alig->SetLastPoint(alig->NbVertex());
157   }
158 }
159 //=======================================================================
160 //function : IntCyCy
161 //purpose  : 
162 //=======================================================================
163 Standard_Boolean IntCyCy(const IntSurf_Quadric& Quad1,
164                          const IntSurf_Quadric& Quad2,
165                          const Standard_Real Tol,
166                          Standard_Boolean& Empty,
167                          Standard_Boolean& Same,
168                          Standard_Boolean& Multpoint,
169                          IntPatch_SequenceOfLine& slin,
170                          IntPatch_SequenceOfPoint& spnt)
171
172 {
173   IntPatch_Point ptsol;
174
175   Standard_Integer i;
176
177   IntSurf_TypeTrans trans1,trans2;
178   IntAna_ResultType typint;
179
180   gp_Elips elipsol;
181   gp_Lin linsol;
182
183   gp_Cylinder Cy1(Quad1.Cylinder());
184   gp_Cylinder Cy2(Quad2.Cylinder());
185
186   IntAna_QuadQuadGeo inter(Cy1,Cy2,Tol);
187
188   if (!inter.IsDone()) {return Standard_False;}
189
190   typint = inter.TypeInter();
191   Standard_Integer NbSol = inter.NbSolutions();
192   Empty = Standard_False;
193   Same  = Standard_False;
194
195   switch (typint) {
196
197   case IntAna_Empty :
198     {
199       Empty = Standard_True;
200     }
201     break;
202
203   case IntAna_Same:
204     {
205       Same  = Standard_True;
206     }
207     break;
208
209
210   case IntAna_Point :
211     {
212       gp_Pnt psol(inter.Point(1));
213       Standard_Real U1,V1,U2,V2;
214       Quad1.Parameters(psol,U1,V1);
215       Quad2.Parameters(psol,U2,V2);
216       ptsol.SetValue(psol,Tol,Standard_True);
217       ptsol.SetParameters(U1,V1,U2,V2);
218       spnt.Append(ptsol);
219     }
220     break;
221
222   case IntAna_Line:
223     {
224       gp_Pnt ptref;
225       if (NbSol == 1) { // ligne de tangence
226         linsol = inter.Line(1);
227         ptref = linsol.Location();
228         gp_Dir crb1(gp_Vec(ptref,Cy1.Location()));
229         gp_Dir crb2(gp_Vec(ptref,Cy2.Location()));
230         gp_Vec norm1(Quad1.Normale(ptref));
231         gp_Vec norm2(Quad2.Normale(ptref));
232         IntSurf_Situation situcyl1;
233         IntSurf_Situation situcyl2;
234
235         if (crb1.Dot(crb2) < 0.) { // centre de courbures "opposes"
236           if (norm1.Dot(crb1) > 0.) {
237             situcyl2 = IntSurf_Inside;
238           }
239           else {
240             situcyl2 = IntSurf_Outside;
241           }
242           if (norm2.Dot(crb2) > 0.) {
243             situcyl1 = IntSurf_Inside;
244           }
245           else {
246             situcyl1 = IntSurf_Outside;
247           }
248         }
249         else {
250           if (Cy1.Radius() < Cy2.Radius()) {
251             if (norm1.Dot(crb1) > 0.) {
252               situcyl2 = IntSurf_Inside;
253             }
254             else {
255               situcyl2 = IntSurf_Outside;
256             }
257             if (norm2.Dot(crb2) > 0.) {
258               situcyl1 = IntSurf_Outside;
259             }
260             else {
261               situcyl1 = IntSurf_Inside;
262             }
263           }
264           else {
265             if (norm1.Dot(crb1) > 0.) {
266               situcyl2 = IntSurf_Outside;
267             }
268             else {
269               situcyl2 = IntSurf_Inside;
270             }
271             if (norm2.Dot(crb2) > 0.) {
272               situcyl1 = IntSurf_Inside;
273             }
274             else {
275               situcyl1 = IntSurf_Outside;
276             }
277           }
278         }
279         Handle(IntPatch_GLine) glig =  new IntPatch_GLine(linsol, Standard_True, situcyl1, situcyl2);
280         slin.Append(glig);
281       }
282       else {
283         for (i=1; i <= NbSol; i++) {
284           linsol = inter.Line(i);
285           ptref = linsol.Location();
286           gp_Vec lsd = linsol.Direction();
287           Standard_Real qwe = lsd.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
288           if (qwe >0.00000001) {
289             trans1 = IntSurf_Out;
290             trans2 = IntSurf_In;
291           }
292           else if (qwe <-0.00000001) {
293             trans1 = IntSurf_In;
294             trans2 = IntSurf_Out;
295           }
296           else {
297             trans1=trans2=IntSurf_Undecided; 
298           }
299           
300           Handle(IntPatch_GLine) glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
301           slin.Append(glig);
302         }
303       }
304     }
305     break;
306     
307   case IntAna_Ellipse:
308     {
309       gp_Vec Tgt;
310       gp_Pnt ptref;
311       IntPatch_Point pmult1;
312       IntPatch_Point pmult2;
313       elipsol = inter.Ellipse(1);
314       gp_Pnt pttang1(ElCLib::Value(PI*0.5,elipsol));
315       gp_Pnt pttang2(ElCLib::Value(1.5*PI,elipsol));
316       
317       Multpoint = Standard_True;
318       pmult1.SetValue(pttang1,Tol,Standard_True);
319       pmult2.SetValue(pttang2,Tol,Standard_True);
320       pmult1.SetMultiple(Standard_True);
321       pmult2.SetMultiple(Standard_True);
322       
323       Standard_Real oU1,oV1,oU2,oV2;
324       Quad1.Parameters(pttang1,oU1,oV1); 
325       Quad2.Parameters(pttang1,oU2,oV2);
326       pmult1.SetParameters(oU1,oV1,oU2,oV2);
327
328       Quad1.Parameters(pttang2,oU1,oV1); 
329       Quad2.Parameters(pttang2,oU2,oV2);
330       pmult2.SetParameters(oU1,oV1,oU2,oV2);
331
332
333       // on traite la premiere ellipse
334
335       //-- Calcul de la Transition de la ligne 
336       ElCLib::D1(0.,elipsol,ptref,Tgt);
337       Standard_Real qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
338       if (qwe>0.00000001) {
339         trans1 = IntSurf_Out;
340         trans2 = IntSurf_In;
341       }
342       else if (qwe<-0.00000001) {
343         trans1 = IntSurf_In;
344         trans2 = IntSurf_Out;
345       }
346       else { 
347         trans1=trans2=IntSurf_Undecided; 
348       }
349       //-- Transition calculee au point 0 -> Trans2 , Trans1 
350       //-- car ici, on devarit calculer en PI
351       Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1);
352       pmult1.SetParameter(PI/2.);
353       glig->AddVertex(pmult1);
354       glig->SetFirstPoint(1);
355       pmult2.SetParameter(1.5*PI);
356       glig->AddVertex(pmult2);
357       glig->SetLastPoint(2);
358       slin.Append(glig);
359       
360       //-- Transitions calculee au point 0    OK
361       glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
362       pmult2.SetParameter(-PI/2.);
363       glig->AddVertex(pmult2);
364       glig->SetFirstPoint(1);
365       glig->AddVertex(pmult1);
366       glig->SetLastPoint(2);
367       slin.Append(glig);
368
369
370       // on traite la deuxieme ellipse
371
372       elipsol = inter.Ellipse(2);
373
374       Standard_Real param1 = ElCLib::Parameter(elipsol,pttang1);
375       Standard_Real param2 = ElCLib::Parameter(elipsol,pttang2);
376       Standard_Real parampourtransition;
377       if (param1 < param2) {
378         pmult1.SetParameter(PI*0.5);
379         pmult2.SetParameter(1.5*PI);
380         parampourtransition = PI;
381       }
382       else {
383         pmult1.SetParameter(-PI*0.5);
384         pmult2.SetParameter(PI*0.5);
385         parampourtransition = 0.0;
386       }
387       
388       //-- Calcul des transitions de ligne pour la premiere ligne 
389       ElCLib::D1(parampourtransition,elipsol,ptref,Tgt);      
390       qwe=Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
391       if(qwe> 0.00000001) {
392         trans1 = IntSurf_Out;
393         trans2 = IntSurf_In;
394       }
395       else if(qwe< -0.00000001) {
396         trans1 = IntSurf_In;
397         trans2 = IntSurf_Out;
398       }
399       else { 
400         trans1=trans2=IntSurf_Undecided;
401       }
402       //-- La transition a ete calculee sur un point de cette ligne 
403       glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
404       glig->AddVertex(pmult1);
405       glig->SetFirstPoint(1);
406       glig->AddVertex(pmult2);
407       glig->SetLastPoint(2);
408       slin.Append(glig);
409       
410       if (param1 < param2) {
411         pmult2.SetParameter(-PI*0.5);
412       }
413       else {
414         pmult1.SetParameter(1.5*PI);
415       }
416       
417       //-- Sur l'autre ligne, on invertse la transition
418       glig = new IntPatch_GLine(elipsol,Standard_False,trans2,trans1);
419       glig->AddVertex(pmult2);
420       glig->SetFirstPoint(1);
421       glig->AddVertex(pmult1);
422       glig->SetLastPoint(2);
423       slin.Append(glig);
424     }
425     break;
426     
427
428   case IntAna_NoGeometricSolution:
429     {
430       Standard_Boolean bReverse;
431       Standard_Real U1,V1,U2,V2;
432       gp_Pnt psol;
433       //
434       bReverse=IsToReverse(Cy1, Cy2, Tol);
435       if (bReverse){
436         Cy2=Quad1.Cylinder();
437         Cy1=Quad2.Cylinder();
438       }
439       //
440       IntAna_IntQuadQuad anaint(Cy1,Cy2,Tol);
441       if (!anaint.IsDone()) {
442         return Standard_False;
443       }
444       
445       if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
446         Empty = Standard_True;
447       }
448       else {
449         NbSol = anaint.NbPnt();
450         for (i = 1; i <= NbSol; i++) {
451           psol = anaint.Point(i);
452           Quad1.Parameters(psol,U1,V1);
453           Quad2.Parameters(psol,U2,V2);
454           ptsol.SetValue(psol,Tol,Standard_True);
455           ptsol.SetParameters(U1,V1,U2,V2);
456           spnt.Append(ptsol);
457         }
458         
459         gp_Pnt ptvalid, ptf, ptl;
460         gp_Vec tgvalid;
461         
462         Standard_Real first,last,para;
463         IntAna_Curve curvsol;
464         Standard_Boolean tgfound;
465         Standard_Integer kount;
466         
467         NbSol = anaint.NbCurve();
468         for (i = 1; i <= NbSol; i++) {
469           curvsol = anaint.Curve(i);
470           curvsol.Domain(first,last);
471           ptf = curvsol.Value(first);
472           ptl = curvsol.Value(last);
473           
474           para = last;
475           kount = 1;
476           tgfound = Standard_False;
477           
478           while (!tgfound) {
479             para = (1.123*first + para)/2.123;
480             tgfound = curvsol.D1u(para,ptvalid,tgvalid);
481             if (!tgfound) {
482               kount ++;
483               tgfound = kount > 5;
484             }
485           }
486           Handle(IntPatch_ALine) alig;
487           if (kount <= 5) {
488             Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
489                                                  Quad1.Normale(ptvalid));
490             if(qwe>0.00000001) { 
491               trans1 = IntSurf_Out;
492               trans2 = IntSurf_In;
493             }
494             else if(qwe<-0.00000001) {
495               trans1 = IntSurf_In;
496               trans2 = IntSurf_Out;
497             }
498             else { 
499               trans1=trans2=IntSurf_Undecided; 
500             }
501             alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
502           }
503           else {
504             alig = new IntPatch_ALine(curvsol,Standard_False);
505             //-- cout << "Transition indeterminee" << endl;
506           }
507           Standard_Boolean TempFalse1 = Standard_False;
508           Standard_Boolean TempFalse2 = Standard_False;
509           
510           ProcessBounds(alig,slin,Quad1,Quad2,TempFalse1,ptf,first,
511                         TempFalse2,ptl,last,Multpoint,Tol);
512           slin.Append(alig);
513         }
514       }
515     }
516     break;
517
518   default:
519     {
520       return Standard_False;
521     }
522   }
523   return Standard_True;
524 }
525
526
527 //=======================================================================
528 //function : IntCySp
529 //purpose  : 
530 //=======================================================================
531 Standard_Boolean IntCySp(const IntSurf_Quadric& Quad1,
532                          const IntSurf_Quadric& Quad2,
533                          const Standard_Real Tol,
534                          const Standard_Boolean Reversed,
535                          Standard_Boolean& Empty,
536                          Standard_Boolean& Multpoint,
537                          IntPatch_SequenceOfLine& slin,
538                          IntPatch_SequenceOfPoint& spnt)
539
540 {
541   Standard_Integer i;
542
543   IntSurf_TypeTrans trans1,trans2;
544   IntAna_ResultType typint;
545   IntPatch_Point ptsol;
546   gp_Circ cirsol;
547
548   gp_Cylinder Cy;
549   gp_Sphere Sp;
550
551   if (!Reversed) {
552     Cy = Quad1.Cylinder();
553     Sp = Quad2.Sphere();
554   }
555   else {
556     Cy = Quad2.Cylinder();
557     Sp = Quad1.Sphere();
558   }
559   IntAna_QuadQuadGeo inter(Cy,Sp,Tol);
560
561   if (!inter.IsDone()) {return Standard_False;}
562
563   typint = inter.TypeInter();
564   Standard_Integer NbSol = inter.NbSolutions();
565   Empty = Standard_False;
566
567   switch (typint) {
568
569   case IntAna_Empty :
570     {
571       Empty = Standard_True;
572     }
573     break;
574
575   case IntAna_Point :
576     {
577       gp_Pnt psol(inter.Point(1));
578       Standard_Real U1,V1,U2,V2;
579       Quad1.Parameters(psol,U1,V1);
580       Quad2.Parameters(psol,U2,V2);
581       ptsol.SetValue(psol,Tol,Standard_True);
582       ptsol.SetParameters(U1,V1,U2,V2);
583       spnt.Append(ptsol);
584     }
585     break;
586
587   case IntAna_Circle:
588     {
589       cirsol = inter.Circle(1);
590       gp_Vec Tgt;
591       gp_Pnt ptref;
592       ElCLib::D1(0.,cirsol,ptref,Tgt);
593
594       if (NbSol == 1) {
595         gp_Vec TestCurvature(ptref,Sp.Location());
596         gp_Vec Normsp,Normcyl;
597         if (!Reversed) {
598           Normcyl = Quad1.Normale(ptref);
599           Normsp  = Quad2.Normale(ptref);
600         }
601         else {
602           Normcyl = Quad2.Normale(ptref);
603           Normsp  = Quad1.Normale(ptref);
604         }
605         
606         IntSurf_Situation situcyl;
607         IntSurf_Situation situsp;
608         
609         if (Normcyl.Dot(TestCurvature) > 0.) {
610           situsp = IntSurf_Outside;
611           if (Normsp.Dot(Normcyl) > 0.) {
612             situcyl = IntSurf_Inside;
613           }
614           else {
615             situcyl = IntSurf_Outside;
616           }
617         }
618         else {
619           situsp = IntSurf_Inside;
620           if (Normsp.Dot(Normcyl) > 0.) {
621             situcyl = IntSurf_Outside;
622           }
623           else {
624             situcyl = IntSurf_Inside;
625           }
626         }
627         Handle(IntPatch_GLine) glig;
628         if (!Reversed) {
629           glig = new IntPatch_GLine(cirsol, Standard_True, situcyl, situsp);
630         }
631         else {
632           glig = new IntPatch_GLine(cirsol, Standard_True, situsp, situcyl);
633         }
634         slin.Append(glig);
635       }
636       else {
637         if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
638           trans1 = IntSurf_Out;
639           trans2 = IntSurf_In;
640         }
641         else {
642           trans1 = IntSurf_In;
643           trans2 = IntSurf_Out;
644         }
645         Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
646         slin.Append(glig);
647
648         cirsol = inter.Circle(2);
649         ElCLib::D1(0.,cirsol,ptref,Tgt);
650         Standard_Real qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
651         if(qwe> 0.0000001) {
652           trans1 = IntSurf_Out;
653           trans2 = IntSurf_In;
654         }
655         else if(qwe<-0.0000001) {
656           trans1 = IntSurf_In;
657           trans2 = IntSurf_Out;
658         }
659         else { 
660           trans1=trans2=IntSurf_Undecided; 
661         }
662         glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
663         slin.Append(glig);
664       }
665     }
666     break;
667     
668   case IntAna_NoGeometricSolution:
669     {
670       gp_Pnt psol;
671       Standard_Real U1,V1,U2,V2;
672       IntAna_IntQuadQuad anaint(Cy,Sp,Tol);
673       if (!anaint.IsDone()) {
674         return Standard_False;
675       }
676
677       if (anaint.NbPnt()==0 && anaint.NbCurve()==0) {
678         Empty = Standard_True;
679       }
680       else {
681
682         NbSol = anaint.NbPnt();
683         for (i = 1; i <= NbSol; i++) {
684           psol = anaint.Point(i);
685           Quad1.Parameters(psol,U1,V1);
686           Quad2.Parameters(psol,U2,V2);
687           ptsol.SetValue(psol,Tol,Standard_True);
688           ptsol.SetParameters(U1,V1,U2,V2);
689           spnt.Append(ptsol);
690         }
691         
692         gp_Pnt ptvalid,ptf,ptl;
693         gp_Vec tgvalid;
694         Standard_Real first,last,para;
695         IntAna_Curve curvsol;
696         Standard_Boolean tgfound;
697         Standard_Integer kount;
698         
699         NbSol = anaint.NbCurve();
700         for (i = 1; i <= NbSol; i++) {
701           curvsol = anaint.Curve(i);
702           curvsol.Domain(first,last);
703           ptf = curvsol.Value(first);
704           ptl = curvsol.Value(last);
705
706           para = last;
707           kount = 1;
708           tgfound = Standard_False;
709           
710           while (!tgfound) {
711             para = (1.123*first + para)/2.123;
712             tgfound = curvsol.D1u(para,ptvalid,tgvalid);
713             if (!tgfound) {
714               kount ++;
715               tgfound = kount > 5;
716             }
717           }
718           Handle(IntPatch_ALine) alig;
719           if (kount <= 5) {
720             Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
721                                                  Quad1.Normale(ptvalid));
722             if(qwe> 0.00000001) {
723               trans1 = IntSurf_Out;
724               trans2 = IntSurf_In;
725             }
726             else if(qwe<-0.00000001) {
727               trans1 = IntSurf_In;
728               trans2 = IntSurf_Out;
729             }
730             else { 
731               trans1=trans2=IntSurf_Undecided; 
732             }
733             alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
734           }
735           else {
736             alig = new IntPatch_ALine(curvsol,Standard_False);
737           }
738           Standard_Boolean TempFalse1a = Standard_False;
739           Standard_Boolean TempFalse2a = Standard_False;
740
741           //-- ptf et ptl : points debut et fin de alig 
742           
743           ProcessBounds(alig,slin,Quad1,Quad2,TempFalse1a,ptf,first,
744                         TempFalse2a,ptl,last,Multpoint,Tol);
745           slin.Append(alig);
746         } //-- boucle sur les lignes 
747       } //-- solution avec au moins une lihne 
748     }
749     break;
750
751   default:
752     {
753       return Standard_False;
754     }
755   }
756   return Standard_True;
757 }
758 //=======================================================================
759 //function : IntCyCo
760 //purpose  : 
761 //=======================================================================
762 Standard_Boolean IntCyCo(const IntSurf_Quadric& Quad1,
763                          const IntSurf_Quadric& Quad2,
764                          const Standard_Real Tol,
765                          const Standard_Boolean Reversed,
766                          Standard_Boolean& Empty,
767                          Standard_Boolean& Multpoint,
768                          IntPatch_SequenceOfLine& slin,
769                          IntPatch_SequenceOfPoint& spnt)
770
771 {
772   IntPatch_Point ptsol;
773
774   Standard_Integer i;
775
776   IntSurf_TypeTrans trans1,trans2;
777   IntAna_ResultType typint;
778   gp_Circ cirsol;
779
780   gp_Cylinder Cy;
781   gp_Cone     Co;
782
783   if (!Reversed) {
784     Cy = Quad1.Cylinder();
785     Co = Quad2.Cone();
786   }
787   else {
788     Cy = Quad2.Cylinder();
789     Co = Quad1.Cone();
790   }
791   IntAna_QuadQuadGeo inter(Cy,Co,Tol);
792
793   if (!inter.IsDone()) {return Standard_False;}
794
795   typint = inter.TypeInter();
796   Standard_Integer NbSol = inter.NbSolutions();
797   Empty = Standard_False;
798
799   switch (typint) {
800
801   case IntAna_Empty : {
802     Empty = Standard_True;
803   }
804     break;
805
806   case IntAna_Point :{
807     gp_Pnt psol(inter.Point(1));
808     Standard_Real U1,V1,U2,V2;
809     Quad1.Parameters(psol,U1,V1);
810     Quad1.Parameters(psol,U2,V2);
811     ptsol.SetValue(psol,Tol,Standard_True);
812     ptsol.SetParameters(U1,V1,U2,V2);
813     spnt.Append(ptsol);
814   }
815     break;
816     
817   case IntAna_Circle:  {
818     gp_Vec Tgt;
819     gp_Pnt ptref;
820     Standard_Integer j;
821     Standard_Real qwe;
822     //
823     for(j=1; j<=2; ++j) { 
824       cirsol = inter.Circle(j);
825       ElCLib::D1(0.,cirsol,ptref,Tgt);
826       qwe = Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref));
827       if(qwe> 0.00000001) {
828         trans1 = IntSurf_Out;
829         trans2 = IntSurf_In;
830       }
831       else if(qwe<-0.00000001) {
832         trans1 = IntSurf_In;
833         trans2 = IntSurf_Out;
834       }
835       else { 
836         trans1=trans2=IntSurf_Undecided; 
837       }
838       Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
839       slin.Append(glig);
840     }
841   }
842     break;
843     
844   case IntAna_NoGeometricSolution:    {
845     gp_Pnt psol;
846     Standard_Real U1,V1,U2,V2;
847     IntAna_IntQuadQuad anaint(Cy,Co,Tol);
848     if (!anaint.IsDone()) {
849       return Standard_False;
850     }
851     
852     if (anaint.NbPnt() == 0 && anaint.NbCurve() == 0) {
853       Empty = Standard_True;
854     }
855     else {
856       NbSol = anaint.NbPnt();
857       for (i = 1; i <= NbSol; i++) {
858         psol = anaint.Point(i);
859         Quad1.Parameters(psol,U1,V1);
860         Quad2.Parameters(psol,U2,V2);
861         ptsol.SetValue(psol,Tol,Standard_True);
862         ptsol.SetParameters(U1,V1,U2,V2);
863         spnt.Append(ptsol);
864       }
865       
866       gp_Pnt ptvalid, ptf, ptl;
867       gp_Vec tgvalid;
868       //
869       Standard_Real first,last,para;
870       Standard_Boolean tgfound,firstp,lastp,kept;
871       Standard_Integer kount;
872       //
873       //
874       //IntAna_Curve curvsol;
875       IntAna_Curve aC;
876       IntAna_ListOfCurve aLC;
877       IntAna_ListIteratorOfListOfCurve aIt;
878       Standard_Boolean bToSplit;
879       
880       //
881       NbSol = anaint.NbCurve();
882       for (i = 1; i <= NbSol; ++i) {
883         kept = Standard_False;
884         //curvsol = anaint.Curve(i);
885         aC=anaint.Curve(i);
886         aLC.Clear();
887         bToSplit=ExploreCurve(Cy, Co, aC, 10.*Tol, aLC);
888         //
889         aIt.Initialize(aLC);
890         for (; aIt.More(); aIt.Next()) {
891           IntAna_Curve& curvsol=aIt.Value();
892           //
893           curvsol.Domain(first, last);
894           firstp = !curvsol.IsFirstOpen();
895           lastp  = !curvsol.IsLastOpen();
896           if (firstp) {
897             ptf = curvsol.Value(first);
898           }
899           if (lastp) {
900             ptl = curvsol.Value(last);
901           }
902           para = last;
903           kount = 1;
904           tgfound = Standard_False;
905           
906           while (!tgfound) {
907             para = (1.123*first + para)/2.123;
908             tgfound = curvsol.D1u(para,ptvalid,tgvalid);
909             if (!tgfound) {
910               kount ++;
911               tgfound = kount > 5;
912             }
913           }
914           Handle(IntPatch_ALine) alig;
915           if (kount <= 5) {
916             Standard_Real qwe = tgvalid.DotCross(Quad2.Normale(ptvalid),
917                                                  Quad1.Normale(ptvalid));
918             if(qwe> 0.00000001) {
919               trans1 = IntSurf_Out;
920               trans2 = IntSurf_In;
921             }
922             else if(qwe<-0.00000001) {
923               trans1 = IntSurf_In;
924               trans2 = IntSurf_Out;
925             }
926             else { 
927               trans1=trans2=IntSurf_Undecided; 
928             }
929             alig = new IntPatch_ALine(curvsol,Standard_False,trans1,trans2);
930             kept = Standard_True;
931           }
932           else {
933             ptvalid = curvsol.Value(para);
934             alig = new IntPatch_ALine(curvsol,Standard_False);
935             kept = Standard_True;
936             //-- cout << "Transition indeterminee" << endl;
937           }
938           if (kept) {
939             Standard_Boolean Nfirstp = !firstp;
940             Standard_Boolean Nlastp  = !lastp;
941             ProcessBounds(alig,slin,Quad1,Quad2,Nfirstp,ptf,first,
942                           Nlastp,ptl,last,Multpoint,Tol);
943             slin.Append(alig);
944           }
945         } // for (; aIt.More(); aIt.Next())
946       } // for (i = 1; i <= NbSol; ++i) 
947     }
948   }
949     break;
950     
951   default:
952     return Standard_False;
953     
954   } // switch (typint)
955   
956   return Standard_True;
957 }
958 //=======================================================================
959 //function : ExploreCurve
960 //purpose  : 
961 //=======================================================================
962 Standard_Boolean ExploreCurve(const gp_Cylinder& ,//aCy,
963                               const gp_Cone& aCo,
964                               IntAna_Curve& aC,
965                               const Standard_Real aTol,
966                               IntAna_ListOfCurve& aLC)
967                               
968 {
969   Standard_Boolean bFind=Standard_False;
970   Standard_Real aTheta, aT1, aT2, aDst;
971   gp_Pnt aPapx, aPx;
972   //
973   //aC.Dump();
974   //
975   aLC.Clear();
976   aLC.Append(aC);
977   //
978   aPapx=aCo.Apex();
979   //
980   aC.Domain(aT1, aT2);
981   //
982   aPx=aC.Value(aT1);
983   aDst=aPx.Distance(aPapx);
984   if (aDst<aTol) {
985     return bFind;
986   }
987   aPx=aC.Value(aT2);
988   aDst=aPx.Distance(aPapx);
989   if (aDst<aTol) {
990     return bFind;
991   }
992   //
993   bFind=aC.FindParameter(aPapx, aTheta);
994   if (!bFind){
995     return bFind;
996   }
997   //
998   aPx=aC.Value(aTheta);
999   aDst=aPx.Distance(aPapx);
1000   if (aDst>aTol) {
1001     return !bFind;
1002   }
1003   //
1004   // need to be splitted at aTheta
1005   IntAna_Curve aC1, aC2;
1006   //
1007   aC1=aC;
1008   aC1.SetDomain(aT1, aTheta);
1009   aC2=aC;
1010   aC2.SetDomain(aTheta, aT2);
1011   //
1012   aLC.Clear();
1013   aLC.Append(aC1);
1014   aLC.Append(aC2);
1015   //
1016   return bFind;
1017 }
1018 //=======================================================================
1019 //function : IsToReverse
1020 //purpose  : 
1021 //=======================================================================
1022 Standard_Boolean IsToReverse(const gp_Cylinder& Cy1,
1023                              const gp_Cylinder& Cy2,
1024                              const Standard_Real Tol)
1025 {
1026   Standard_Boolean bRet;
1027   Standard_Real aR1,aR2, dR, aSc1, aSc2;
1028   //
1029   bRet=Standard_False;
1030   //
1031   aR1=Cy1.Radius();
1032   aR2=Cy2.Radius();
1033   dR=aR1-aR2;
1034   if (dR<0.) {
1035     dR=-dR;
1036   }
1037   if (dR>Tol) {
1038     bRet=aR1>aR2;
1039   }
1040   else {
1041     gp_Dir aDZ(0.,0.,1.);
1042     //
1043     const gp_Dir& aDir1=Cy1.Axis().Direction();
1044     aSc1=aDir1*aDZ;
1045     if (aSc1<0.) {
1046       aSc1=-aSc1;
1047     }
1048     //
1049     const gp_Dir& aDir2=Cy2.Axis().Direction();
1050     aSc2=aDir2*aDZ;
1051     if (aSc2<0.) {
1052       aSc2=-aSc2;
1053     }
1054     //
1055     if (aSc2<aSc1) {
1056       bRet=!bRet;
1057     }
1058   }//if (dR<Tol) {
1059   return bRet;
1060 }