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