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