0029807: [Regression to 7.0.0] Impossible to cut cone from prism
[occt.git] / src / IntPatch / IntPatch_ImpImpIntersection_3.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 under
9 // the terms of the GNU Lesser General Public License 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 //modified by NIZNHY-PKV Thu Sep 15 11:09:12 2011
18 static 
19   void SeamPosition(const gp_Pnt& aPLoc, 
20                     const gp_Ax3& aPos,
21                     gp_Ax2& aSeamPos);
22 static
23   void AdjustToSeam (const gp_Cylinder& aQuad,
24                      gp_Circ& aCirc);
25 static
26   void AdjustToSeam (const gp_Sphere& aQuad,
27                      gp_Circ& aCirc,
28                      const Standard_Real aTolAng);
29 static
30   void AdjustToSeam (const gp_Cone& aQuad,
31                      gp_Circ& aCirc);
32 static
33   void AdjustToSeam (const gp_Torus& aQuad,
34                      gp_Circ& aCirc);
35 //modified by NIZNHY-PKV Thu Sep 15 11:09:13 2011
36
37 //=======================================================================
38 //function : IntPP
39 //purpose  : 
40 // Traitement du cas Plan/Plan
41 //=======================================================================
42 Standard_Boolean IntPP (const IntSurf_Quadric& Quad1,
43                         const IntSurf_Quadric& Quad2,
44                         const Standard_Real Tolang,
45                         const Standard_Real TolTang,
46                         Standard_Boolean& Same,
47                         IntPatch_SequenceOfLine& slin)
48
49 {
50   IntSurf_TypeTrans trans1,trans2;
51   IntAna_ResultType typint;
52   gp_Pln pl1(Quad1.Plane());
53   gp_Pln pl2(Quad2.Plane());
54   
55   IntAna_QuadQuadGeo inter(pl1,pl2,Tolang,TolTang);
56   if (!inter.IsDone()) {return Standard_False;}
57   Same = Standard_False;
58   typint = inter.TypeInter();
59   if (typint == IntAna_Same) { // cas faces confondues
60     Same = Standard_True;
61   }
62   else if (typint != IntAna_Empty) { // on a une ligne
63     gp_Lin linsol = inter.Line(1);
64     Standard_Real discri = linsol.Direction().DotCross
65       (Quad2.Normale(linsol.Location()),
66        Quad1.Normale(linsol.Location()));
67     
68     if (discri>0.0) {
69       trans1 = IntSurf_Out;
70       trans2 = IntSurf_In;
71     }
72     else {
73       trans1 = IntSurf_In;
74       trans2 = IntSurf_Out;
75     }
76     Handle(IntPatch_GLine) glig = 
77       new IntPatch_GLine (linsol,Standard_False,trans1,trans2);
78     slin.Append(glig);
79   }
80   return Standard_True;
81 }
82 //=======================================================================
83 //function : IntPCy
84 //purpose  : 
85 // Traitement du cas Plan/Cylindre et reciproquement
86 //=======================================================================
87 Standard_Boolean IntPCy (const IntSurf_Quadric& Quad1,
88                          const IntSurf_Quadric& Quad2,
89                          const Standard_Real Tolang,
90                          const Standard_Real TolTang,
91                          const Standard_Boolean Reversed,
92                          Standard_Boolean& Empty,
93                          IntPatch_SequenceOfLine& slin,
94                          const Standard_Real H)
95
96 {
97   gp_Pln Pl;
98   gp_Cylinder Cy;
99
100   IntSurf_TypeTrans trans1,trans2;
101   IntAna_ResultType typint;
102
103   IntAna_QuadQuadGeo inter;
104   if (!Reversed) {
105     Pl = Quad1.Plane();
106     Cy = Quad2.Cylinder();
107   }
108   else {
109     Pl = Quad2.Plane();
110     Cy = Quad1.Cylinder();
111   }
112   inter.Perform(Pl,Cy,Tolang,TolTang,H);
113   if (!inter.IsDone()) {return Standard_False;}
114   typint = inter.TypeInter();
115   Standard_Integer NbSol = inter.NbSolutions();
116   Empty = Standard_False;
117
118   switch (typint) {
119             
120     case IntAna_Empty :    {
121       Empty = Standard_True;
122     }
123       break;
124
125     case IntAna_Line:    {
126       gp_Lin linsol = inter.Line(1);
127       gp_Pnt orig(linsol.Location());
128       if (NbSol == 1) {                 // ligne de tangence
129         gp_Vec TestCurvature(orig,Cy.Location());
130         gp_Vec Normp,Normcyl;
131         if (!Reversed) {
132           Normp = Quad1.Normale(orig);
133           Normcyl = Quad2.Normale(orig);
134         }
135         else {
136           Normp = Quad2.Normale(orig);
137           Normcyl = Quad1.Normale(orig);
138         }
139         
140         IntSurf_Situation situcyl;
141         IntSurf_Situation situp;
142
143         if (Normp.Dot(TestCurvature) > 0.) {
144           situcyl = IntSurf_Outside;
145           if (Normp.Dot(Normcyl) > 0.) {
146             situp = IntSurf_Inside;
147           }
148           else {
149             situp = IntSurf_Outside;
150           }
151         }
152         else {
153           situcyl = IntSurf_Inside;
154           if (Normp.Dot(Normcyl) > 0.) {
155             situp = IntSurf_Outside;
156           }
157           else {
158             situp = IntSurf_Inside;
159           }
160         }
161         Handle(IntPatch_GLine) glig;
162         if (!Reversed) {
163           glig = new IntPatch_GLine(linsol, Standard_True, situp, situcyl);
164         }
165         else {
166           glig = new IntPatch_GLine(linsol, Standard_True, situcyl, situp);
167         }
168         slin.Append(glig);
169       }
170       else {      
171         // on a 2 droites. Il faut determiner les transitions
172         // de chacune.
173         
174         if (linsol.Direction().DotCross(Quad2.Normale(orig),
175                                         Quad1.Normale(orig)) >0.) {
176           trans1 = IntSurf_Out;
177           trans2 = IntSurf_In;
178         }
179         else {
180           trans1 = IntSurf_In;
181           trans2 = IntSurf_Out;
182         }
183         Handle(IntPatch_GLine) glig = 
184           new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
185         slin.Append(glig);
186         
187         linsol = inter.Line(2);
188         orig = linsol.Location();
189
190         if (linsol.Direction().DotCross(Quad2.Normale(orig),
191                                         Quad1.Normale(orig)) >0.) {
192           trans1 = IntSurf_Out;
193           trans2 = IntSurf_In;
194         }
195         else {
196           trans1 = IntSurf_In;
197           trans2 = IntSurf_Out;
198         }
199         glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
200         slin.Append(glig);
201       }
202     }
203       break;
204       //
205     case IntAna_Circle:    {
206       gp_Circ cirsol;
207       gp_Pnt ptref;
208       gp_Vec Tgt;
209       //
210       cirsol = inter.Circle(1);
211       //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
212       AdjustToSeam(Cy, cirsol);
213       //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
214       ElCLib::D1(0.,cirsol,ptref,Tgt);
215       
216       if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
217         trans1 = IntSurf_Out;
218         trans2 = IntSurf_In;
219       }
220       else {
221         trans1 = IntSurf_In;
222         trans2 = IntSurf_Out;
223       }
224       Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
225       slin.Append(glig);
226     }
227       break;
228       // 
229     case IntAna_Ellipse:    {
230       gp_Elips elipsol = inter.Ellipse(1);
231       gp_Pnt ptref;
232       gp_Vec Tgt;
233       ElCLib::D1(0.,elipsol,ptref,Tgt);
234       
235       if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) > 0.0) {
236         trans1 = IntSurf_Out;
237         trans2 = IntSurf_In;
238       }
239       else {
240         trans1 = IntSurf_In;
241         trans2 = IntSurf_Out;
242       }
243       Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
244       slin.Append(glig);
245     }
246       break;
247       //
248     default:    {
249       return Standard_False; // on ne doit pas passer ici
250     }
251   }
252   return Standard_True;
253 }
254 //=======================================================================
255 //function : IntPSp
256 //purpose  : 
257 // Traitement du cas Plan/Sphere et reciproquement
258 //=======================================================================
259 Standard_Boolean IntPSp (const IntSurf_Quadric& Quad1,
260                          const IntSurf_Quadric& Quad2,
261                          //modified by NIZNHY-PKV Tue Sep 20 08:59:36 2011f
262                          const Standard_Real Tolang,
263                          //modified by NIZNHY-PKV Tue Sep 20 08:59:39 2011t
264                          const Standard_Real TolTang,
265                          const Standard_Boolean Reversed,
266                          Standard_Boolean& Empty,
267                          IntPatch_SequenceOfLine& slin,
268                          IntPatch_SequenceOfPoint& spnt)
269
270
271 {
272   gp_Circ cirsol;
273   gp_Pln Pl;
274   gp_Sphere Sp;
275   IntSurf_TypeTrans trans1,trans2;
276   IntAna_ResultType typint;
277
278   IntAna_QuadQuadGeo inter;
279   if (!Reversed) {
280     Pl = Quad1.Plane();
281     Sp = Quad2.Sphere();
282   }
283   else {
284     Pl = Quad2.Plane();
285     Sp = Quad1.Sphere();
286   }
287   inter.Perform(Pl,Sp);
288
289   if (!inter.IsDone()) {return Standard_False;}
290
291   typint = inter.TypeInter();
292   Empty = Standard_False;
293
294   switch (typint) {
295     case IntAna_Empty :    {
296       Empty = Standard_True;
297     }
298       break;
299       //
300     case IntAna_Point:    {
301       gp_Pnt psol = inter.Point(1);
302       Standard_Real U1,V1,U2,V2;
303       Quad1.Parameters(psol,U1,V1);
304       Quad2.Parameters(psol,U2,V2);
305       IntPatch_Point ptsol;
306       ptsol.SetValue(psol,TolTang,Standard_True);
307       ptsol.SetParameters(U1,V1,U2,V2);
308       spnt.Append(ptsol);
309     }
310       break;
311       //
312     case IntAna_Circle:    {
313       cirsol = inter.Circle(1);
314       //modified by NIZNHY-PKV Thu Sep 15 11:30:03 2011f
315       AdjustToSeam(Sp, cirsol, Tolang);
316       //modified by NIZNHY-PKV Thu Sep 15 11:30:15 2011t
317       gp_Pnt ptref;
318       gp_Vec Tgt;
319       ElCLib::D1(0.,cirsol,ptref,Tgt);
320
321       if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
322         trans1 = IntSurf_Out;
323         trans2 = IntSurf_In;
324       }
325       else {
326         trans1 = IntSurf_In;
327         trans2 = IntSurf_Out;
328       }
329       Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
330       slin.Append(glig);
331     }
332       break;
333       
334     default:    {
335       return Standard_False;  // on ne doit pas passer ici
336     }
337   }
338   return Standard_True;
339 }
340 //=======================================================================
341 //function : IntPCo
342 //purpose  : 
343 // Traitement du cas Plan/Cone et reciproquement
344 //=======================================================================
345 Standard_Boolean IntPCo (const IntSurf_Quadric& Quad1,
346                          const IntSurf_Quadric& Quad2,
347                          const Standard_Real Tolang,
348                          const Standard_Real TolTang,
349                          const Standard_Boolean Reversed,
350                          Standard_Boolean& Empty,
351                          Standard_Boolean& Multpoint,
352                          IntPatch_SequenceOfLine& slin,
353                          IntPatch_SequenceOfPoint& spnt)
354
355
356 {
357   gp_Pnt apex;
358
359   gp_Pln Pl;
360   gp_Cone Co;
361
362   IntSurf_TypeTrans trans1,trans2;
363   IntAna_ResultType typint;
364
365   IntAna_QuadQuadGeo inter;
366   if (!Reversed) {
367     Pl = Quad1.Plane();
368     Co = Quad2.Cone();
369     apex = Co.Apex();
370   }
371   else {
372     Pl = Quad2.Plane();
373     Co = Quad1.Cone();
374     apex = Co.Apex();
375   }
376
377   inter.Perform(Pl,Co,Tolang,TolTang);
378   if (!inter.IsDone()) {
379     return Standard_False;
380   }
381   //
382   typint = inter.TypeInter();
383   Standard_Integer NbSol = inter.NbSolutions();
384   Empty = Standard_False;
385
386   switch (typint) {
387     case IntAna_Point:    {
388       gp_Pnt psol = inter.Point(1);
389       Standard_Real U1,V1,U2,V2;
390       Quad1.Parameters(psol,U1,V1);
391       Quad2.Parameters(psol,U2,V2);
392       IntPatch_Point ptsol;
393       ptsol.SetValue(psol,TolTang,Standard_False);
394       ptsol.SetParameters(U1,V1,U2,V2);
395       spnt.Append(ptsol);
396     }
397       break;
398       
399     case IntAna_Line:    {
400       gp_Lin linsol = inter.Line(1);
401       if (linsol.Direction().Dot(Co.Axis().Direction()) <0.) {
402         linsol.SetDirection(linsol.Direction().Reversed());
403       }
404       Standard_Real para = ElCLib::Parameter(linsol, apex);
405       gp_Pnt ptbid (ElCLib::Value(para+5.,linsol));
406       Standard_Real U1,V1,U2,V2;
407       Quad1.Parameters(apex,U1,V1);
408       Quad2.Parameters(apex,U2,V2);
409       
410       if (NbSol == 1) {                 // ligne de tangence
411         IntPatch_Point ptsol;
412         ptsol.SetValue(apex,TolTang,Standard_False);
413         ptsol.SetParameters(U1,V1,U2,V2);
414         ptsol.SetParameter(para);
415         gp_Pnt ptbid2(apex.XYZ() + 5.*Co.Axis().Direction().XYZ());
416         gp_Vec TestCurvature(ptbid,ptbid2);
417         gp_Vec Normp,Normco;
418         if (!Reversed) {
419           Normp = Quad1.Normale(ptbid);
420           Normco = Quad2.Normale(ptbid);
421         }
422         else {
423           Normp = Quad2.Normale(ptbid);
424           Normco = Quad1.Normale(ptbid);
425         }
426         IntSurf_Situation situco,situco_otherside;
427         IntSurf_Situation situp,situp_otherside;
428         
429         if (Normp.Dot(TestCurvature) > 0.) {
430           situco           = IntSurf_Outside;
431           situco_otherside = IntSurf_Inside;
432           if (Normp.Dot(Normco) > 0.) {
433             situp           = IntSurf_Inside;
434             situp_otherside = IntSurf_Outside;
435           }
436           else {
437             situp           = IntSurf_Outside;
438             situp_otherside = IntSurf_Inside;
439           }
440         }
441         else {
442           situco           = IntSurf_Inside;
443           situco_otherside = IntSurf_Outside;
444           if (Normp.Dot(Normco) > 0.) {
445             situp           = IntSurf_Outside;
446             situp_otherside = IntSurf_Inside;
447           }
448           else {
449             situp           = IntSurf_Inside;
450             situp_otherside = IntSurf_Outside;
451           }
452         }
453         //----------------------------------------------------------
454         //--              Apex ---> Cone.Direction
455         //--
456         Handle(IntPatch_GLine) glig;
457         if (!Reversed) {
458           glig = new IntPatch_GLine(linsol, Standard_True, situp, situco);
459         }
460         else {
461           glig = new IntPatch_GLine(linsol, Standard_True, situco, situp);
462         }
463         glig->AddVertex(ptsol);
464         glig->SetFirstPoint(1);
465         slin.Append(glig);
466         //----------------------------------------------------------
467         //--   -Cone.Direction <------- Apex
468         //--
469         linsol.SetDirection(linsol.Direction().Reversed());
470         if (!Reversed) {
471           glig = new IntPatch_GLine(linsol, Standard_True, situp_otherside, situco_otherside);
472         }
473         else {
474           glig = new IntPatch_GLine(linsol, Standard_True, situco_otherside, situp_otherside);
475         }
476         glig->AddVertex(ptsol);
477         glig->SetFirstPoint(1);
478         slin.Append(glig);
479       }
480       else {      
481         // on a 2 droites. Il faut determiner les transitions
482         // de chacune. On oriente chaque ligne dans le sens
483         // de l axe du cone. Les transitions de chaque ligne seront
484         // inverses l une de l autre => on ne fait le calcul que sur
485         // la premiere.
486         if (linsol.Direction().DotCross
487             (Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
488           trans1 = IntSurf_Out;
489           trans2 = IntSurf_In;
490         }
491         else {
492           trans1 = IntSurf_In;
493           trans2 = IntSurf_Out;
494         }
495
496         Multpoint = Standard_True;
497         //------------------------------------------- Ligne 1 -------
498         IntPatch_Point ptsol;
499         ptsol.SetValue(apex,TolTang,Standard_False);
500         ptsol.SetParameters(U1,V1,U2,V2);
501         ptsol.SetParameter(para);
502         ptsol.SetMultiple(Standard_True);
503         Handle(IntPatch_GLine) glig;
504         glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
505         glig->AddVertex(ptsol);
506         glig->SetFirstPoint(1);
507         slin.Append(glig);
508         //-----------------------------------------------------------
509         //-- Other Side : Les transitions restent les memes
510         //--    linsol -> -linsol   et Quad1(2).N -> -Quad1(2).N
511         //-- 
512         linsol.SetDirection(linsol.Direction().Reversed());
513         glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
514         para = ElCLib::Parameter(linsol, apex);
515         ptsol.SetParameter(para);
516         glig->AddVertex(ptsol);
517         glig->SetFirstPoint(1);
518         slin.Append(glig);
519         
520         //------------------------------------------- Ligne 2 -------
521         linsol = inter.Line(2);
522         if (linsol.Direction().Dot(Co.Axis().Direction()) <0.) {
523           linsol.SetDirection(linsol.Direction().Reversed());
524         }
525         para = ElCLib::Parameter(linsol, apex);
526         ptbid  = ElCLib::Value(para+5.,linsol);
527         if (linsol.Direction().DotCross
528             (Quad2.Normale(ptbid),Quad1.Normale(ptbid)) >0.) {
529           trans1 = IntSurf_Out;
530           trans2 = IntSurf_In;
531         }
532         else {
533           trans1 = IntSurf_In;
534           trans2 = IntSurf_Out;
535         }
536         ptsol.SetParameter(para);
537         glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
538         para = ElCLib::Parameter(linsol, apex);
539         ptsol.SetParameter(para);
540         glig->AddVertex(ptsol);
541         glig->SetFirstPoint(1);
542         slin.Append(glig);
543         //-----------------------------------------------------------
544         //-- Other Side : Les transitions restent les memes
545         //--    linsol -> -linsol   et Quad1(2).N -> -Quad1(2).N
546         //-- 
547         linsol.SetDirection(linsol.Direction().Reversed());
548         glig = new IntPatch_GLine(linsol, Standard_False,trans1,trans2);
549         para = ElCLib::Parameter(linsol, apex);
550         ptsol.SetParameter(para);
551         glig->AddVertex(ptsol);
552         glig->SetFirstPoint(1);
553         slin.Append(glig);
554       }
555     }
556     break;
557       
558     case IntAna_Circle:    {
559       gp_Circ cirsol = inter.Circle(1);
560       //modified by NIZNHY-PKV Thu Sep 15 11:34:04 2011f
561       AdjustToSeam(Co, cirsol);
562       //modified by NIZNHY-PKV Thu Sep 15 11:36:08 2011t
563       gp_Pnt ptref;
564       gp_Vec Tgt;
565       ElCLib::D1(0.,cirsol,ptref,Tgt);
566       
567       if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
568         trans1 = IntSurf_Out;
569         trans2 = IntSurf_In;
570       }
571       else {
572         trans1 = IntSurf_In;
573         trans2 = IntSurf_Out;
574       }
575       Handle(IntPatch_GLine) glig = new IntPatch_GLine(cirsol,Standard_False,trans1,trans2);
576       slin.Append(glig);
577     }
578       break;
579       
580     case IntAna_Ellipse:    {
581       gp_Elips  elipsol = inter.Ellipse(1);
582       gp_Pnt ptref;
583       gp_Vec Tgt;
584       ElCLib::D1(0.,elipsol,ptref,Tgt);
585       
586       if (Tgt.DotCross(Quad2.Normale(ptref),Quad1.Normale(ptref)) >0.) {
587         trans1 = IntSurf_Out;
588         trans2 = IntSurf_In;
589       }
590       else {
591         trans1 = IntSurf_In;
592         trans2 = IntSurf_Out;
593       }
594       Handle(IntPatch_GLine) glig = new IntPatch_GLine(elipsol,Standard_False,trans1,trans2);
595       slin.Append(glig);
596     }
597       break;
598       
599     case IntAna_Parabola:    {
600       gp_Parab parabsol = inter.Parabola(1);
601       
602       gp_Vec Tgtorig(parabsol.YAxis().Direction());
603       Standard_Real ptran = Tgtorig.DotCross(Quad2.Normale(parabsol.Location()),
604                                              Quad1.Normale(parabsol.Location()));
605       if (ptran >0.00000001) {
606         trans1 = IntSurf_Out;
607         trans2 = IntSurf_In;
608       }
609       else if (ptran <-0.00000001) {
610         trans1 = IntSurf_In;
611         trans2 = IntSurf_Out;
612       }
613       else { 
614         trans1=trans2=IntSurf_Undecided; 
615       }
616       Handle(IntPatch_GLine) glig = new IntPatch_GLine(parabsol,Standard_False,trans1,trans2);
617       slin.Append(glig);
618     }
619       break;
620       
621     case IntAna_Hyperbola:    {
622       gp_Pnt tophypr;
623       gp_Vec Tgttop;
624       
625       for(Standard_Integer i=1; i<=2; i++) { 
626         gp_Hypr hyprsol = inter.Hyperbola(i);
627         tophypr = ElCLib::Value(hyprsol.MajorRadius(), 
628                                 hyprsol.XAxis());
629         Tgttop = hyprsol.YAxis().Direction();
630         Standard_Real qwe = Tgttop.DotCross(Quad2.Normale(tophypr),
631                                             Quad1.Normale(tophypr));
632         
633         if (qwe>0.00000001) { 
634           trans1 = IntSurf_Out;
635           trans2 = IntSurf_In;
636         }
637         else if (qwe<-0.00000001){
638           trans1 = IntSurf_In;
639           trans2 = IntSurf_Out;
640         }
641         else { 
642           trans1=trans2=IntSurf_Undecided;
643         }
644         Handle(IntPatch_GLine) glig = new IntPatch_GLine(hyprsol,Standard_False,trans1,trans2);
645         slin.Append(glig);
646       }
647     }
648       break;
649       
650     default:    {
651       return Standard_False;
652     }
653   }
654   return Standard_True;
655 }
656 //=======================================================================
657 //function : IntPTo
658 //purpose  : 
659 //=======================================================================
660 Standard_Boolean IntPTo(const IntSurf_Quadric& theQuad1,
661                         const IntSurf_Quadric& theQuad2,
662                         const Standard_Real theTolTang,
663                         const Standard_Boolean bReversed,
664                         Standard_Boolean& bEmpty,
665                         IntPatch_SequenceOfLine& theSeqLin)
666 {
667   const gp_Pln aPln = bReversed ? theQuad2.Plane() : theQuad1.Plane();
668   const gp_Torus aTorus = bReversed ? theQuad1.Torus() : theQuad2.Torus();
669   //
670   IntAna_QuadQuadGeo inter(aPln, aTorus, theTolTang);
671   Standard_Boolean bRet = inter.IsDone();
672   //
673   if (!bRet) {
674     return bRet;
675   }
676   //
677   IntAna_ResultType typint = inter.TypeInter();
678   Standard_Integer NbSol = inter.NbSolutions();
679   bEmpty = Standard_False;
680   //
681   switch (typint) {
682   case IntAna_Empty :
683     bEmpty = Standard_True;
684     break;
685   //
686   case IntAna_Circle : {
687     Standard_Integer i;
688     IntSurf_TypeTrans trans1, trans2;
689     gp_Pnt ptref;
690     gp_Vec Tgt;
691     //
692     for (i = 1; i <= NbSol; ++i) {
693       gp_Circ aC = inter.Circle(i);
694       if (!aPln.Axis().IsNormal(aTorus.Axis(), Precision::Angular())) {
695         AdjustToSeam(aTorus, aC);
696       }
697       ElCLib::D1(0., aC, ptref, Tgt);
698       //
699       if (Tgt.DotCross(theQuad2.Normale(ptref),theQuad1.Normale(ptref)) > 0.0) {
700         trans1 = IntSurf_Out;
701         trans2 = IntSurf_In;
702       }
703       else {
704         trans1 = IntSurf_In;
705         trans2 = IntSurf_Out;
706       }
707       //
708       Handle(IntPatch_GLine) glig = 
709         new IntPatch_GLine(aC, Standard_False, trans1, trans2);
710       theSeqLin.Append(glig);
711     }
712   }
713     break;
714   //
715   case IntAna_NoGeometricSolution:
716   default:
717     bRet = Standard_False;
718     break;
719   }
720   //
721   return bRet;
722 }
723 //
724 //modified by NIZNHY-PKV Thu Sep 15 10:53:39 2011f
725 //=======================================================================
726 //function : AdjustToSeam
727 //purpose  : 
728 //=======================================================================
729 void AdjustToSeam (const gp_Cone& aQuad,
730                    gp_Circ& aCirc)
731 {
732    gp_Ax2 aAx2;
733    //
734    const gp_Pnt& aPLoc=aCirc.Location();
735    const gp_Ax3& aAx3=aQuad.Position();
736    SeamPosition(aPLoc, aAx3, aAx2);
737    aCirc.SetPosition(aAx2);
738
739 //=======================================================================
740 //function : AdjustToSeam
741 //purpose  : 
742 //=======================================================================
743 void AdjustToSeam (const gp_Sphere& aQuad,
744                    gp_Circ& aCirc,
745                    const Standard_Real aTolAng)
746 {
747    gp_Ax2 aAx2;
748    //
749    const gp_Ax1& aAx1C=aCirc.Axis();
750    const gp_Ax3& aAx3=aQuad.Position();
751    const gp_Ax1& aAx1Q=aAx3.Axis();
752    //
753    const gp_Dir& aDirC=aAx1C.Direction();
754    const gp_Dir& aDirQ=aAx1Q.Direction();
755    if (aDirC.IsParallel(aDirQ, aTolAng)) {
756      const gp_Pnt& aPLoc=aCirc.Location();
757      SeamPosition(aPLoc, aAx3, aAx2);
758      aCirc.SetPosition(aAx2);
759    }
760
761 //=======================================================================
762 //function : AdjustToSeam
763 //purpose  : 
764 //=======================================================================
765 void AdjustToSeam (const gp_Cylinder& aQuad,
766                    gp_Circ& aCirc)
767 {
768    gp_Ax2 aAx2;
769    //
770    const gp_Pnt& aPLoc=aCirc.Location();
771    const gp_Ax3& aAx3=aQuad.Position();
772    SeamPosition(aPLoc, aAx3, aAx2);
773    aCirc.SetPosition(aAx2);
774
775 //=======================================================================
776 //function : AdjustToSeam
777 //purpose  : 
778 //=======================================================================
779 void AdjustToSeam (const gp_Torus& aQuad,
780                    gp_Circ& aCirc)
781 {
782   gp_Ax2 aAx2;
783   //
784   const gp_Pnt& aPLoc=aCirc.Location();
785   const gp_Ax3& aAx3=aQuad.Position();
786   SeamPosition(aPLoc, aAx3, aAx2);
787   aCirc.SetPosition(aAx2);
788
789 //=======================================================================
790 //function : SeamPosition
791 //purpose  : 
792 //=======================================================================
793 void SeamPosition(const gp_Pnt& aPLoc, 
794                   const gp_Ax3& aPos, 
795                   gp_Ax2& aSeamPos)
796 {
797   const gp_Dir& aDZ=aPos.Direction();
798   const gp_Dir& aDX=aPos.XDirection();
799   gp_Ax2 aAx2(aPLoc, aDZ, aDX);
800   aSeamPos=aAx2;
801 }
802     
803 //modified by NIZNHY-PKV Thu Sep 15 10:53:41 2011t