0024972: Problem of the influence of the includes order during compilation
[occt.git] / src / IntTools / IntTools_LineConstructor.cxx
1 // Created on: 1995-02-07
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-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 #include <IntTools_LineConstructor.ixx>
18
19 #include <GeomInt_LineTool.hxx>
20 #include <GeomInt_SequenceOfParameterAndOrientation.hxx>
21 #include <GeomInt_ParameterAndOrientation.hxx>
22
23 #include <IntPatch_Point.hxx>
24 #include <IntPatch_GLine.hxx>
25 #include <IntPatch_WLine.hxx>
26 #include <IntPatch_ALine.hxx>
27 #include <IntSurf_Transition.hxx>
28 #include <TopAbs_Orientation.hxx>
29
30
31 #include <Precision.hxx>
32
33 #include <gp_Pnt2d.hxx>
34
35 #include <Adaptor2d_HCurve2d.hxx>
36
37 #include <GeomAdaptor_HSurface.hxx>
38 #include <Standard_ConstructionError.hxx>
39 #include <IntSurf_Quadric.hxx>
40 #include <IntSurf_PntOn2S.hxx>
41 #include <ElCLib.hxx>
42 #include <GeomAbs_SurfaceType.hxx>
43 #include <TColStd_IndexedMapOfInteger.hxx>
44
45 static
46   void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
47                   const gp_Pnt& Ptref,
48                   Standard_Real& U1,
49                   Standard_Real& V1);
50 static
51   void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
52                   const Handle(GeomAdaptor_HSurface)& myHS2,
53                   const gp_Pnt& Ptref,
54                   Standard_Real& U1,
55                   Standard_Real& V1,
56                   Standard_Real& U2,
57                   Standard_Real& V2);
58
59 static 
60   void GLinePoint(const IntPatch_IType typl,
61                   const Handle(IntPatch_GLine)& GLine,
62                   const Standard_Real aT,
63                   gp_Pnt& aP);
64 static
65   void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
66                const Handle(GeomAdaptor_HSurface)& myHS2,
67                Standard_Real& u1,
68                Standard_Real& v1,
69                Standard_Real& u2,
70                Standard_Real& v2);
71
72 //=======================================================================
73 //function : Perform
74 //purpose  : 
75 //=======================================================================
76 void IntTools_LineConstructor::Perform(const Handle(IntPatch_Line)& L)
77 {
78   Standard_Integer i,nbvtx;
79   Standard_Real firstp,lastp;
80   const Standard_Real Tol = Precision::PConfusion() * 35.0;
81   
82   const IntPatch_IType typl = L->ArcType();
83   if(typl == IntPatch_Analytic)  {
84     Standard_Real u1,v1,u2,v2;
85     Handle(IntPatch_ALine)& ALine =  *((Handle(IntPatch_ALine) *)&L);
86     seqp.Clear();
87     nbvtx = GeomInt_LineTool::NbVertex(L);
88     for(i=1;i<nbvtx;i++)   {
89       firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
90       lastp =  GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
91       if(firstp!=lastp)      {
92         const Standard_Real pmid = (firstp+lastp)*0.5;
93         const gp_Pnt Pmid = ALine->Value(pmid);
94         Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
95         Recadre(myHS1,myHS2,u1,v1,u2,v2);
96         const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
97         if(in1 !=  TopAbs_OUT) {
98           const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
99           if(in2 != TopAbs_OUT) { 
100             seqp.Append(firstp);
101             seqp.Append(lastp);
102           }
103         }
104       }
105     }
106     done = Standard_True;
107     return;
108   } // if(typl == IntPatch_Analytic)  {
109   else if(typl == IntPatch_Walking)  {
110     Standard_Real u1,v1,u2,v2;
111     Handle(IntPatch_WLine)& WLine =  *((Handle(IntPatch_WLine) *)&L);
112     seqp.Clear();
113     nbvtx = GeomInt_LineTool::NbVertex(L);
114     for(i=1;i<nbvtx;i++)    { 
115       firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
116       lastp =  GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
117       if(firstp!=lastp) { 
118         if(lastp != firstp+1)  {
119           const Standard_Integer pmid = (Standard_Integer )( (firstp+lastp)/2);
120           const IntSurf_PntOn2S& Pmid = WLine->Point(pmid);
121           Pmid.Parameters(u1,v1,u2,v2);
122           Recadre(myHS1,myHS2,u1,v1,u2,v2);
123           const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
124           if(in1 !=  TopAbs_OUT) {   
125             const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
126             if(in2 != TopAbs_OUT) {   
127               seqp.Append(firstp);
128               seqp.Append(lastp);
129             }
130           }
131         }
132         else {
133           const IntSurf_PntOn2S& Pfirst = WLine->Point((Standard_Integer)(firstp));
134           Pfirst.Parameters(u1,v1,u2,v2);
135           Recadre(myHS1,myHS2,u1,v1,u2,v2);
136           TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
137           if(in1 !=  TopAbs_OUT) {  //-- !=ON donne Pb 
138             TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
139             if(in2 != TopAbs_OUT) { //-- !=ON  
140               const IntSurf_PntOn2S& Plast = WLine->Point((Standard_Integer)(lastp));
141               Plast.Parameters(u1,v1,u2,v2);
142               Recadre(myHS1,myHS2,u1,v1,u2,v2);
143               in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
144               if(in1 !=  TopAbs_OUT) {  //-- !=ON donne Pb 
145                 in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
146                 if(in2 != TopAbs_OUT) {
147                   seqp.Append(firstp);
148                   seqp.Append(lastp);
149                 }
150               }
151             }
152           }
153         }
154       }
155     }
156     //
157     // The One resulting curve consists of 7 segments that are 
158     // connected between each other.
159     // The aim of the block is to reject these segments and have
160     // one segment instead of 7. 
161     //     The other reason to do that is value of TolReached3D=49.
162     //     Why -? It is not known yet. 
163     //                                             PKV 22.Apr.2002
164     //
165     Standard_Integer aNbParts;
166     //
167     aNbParts = seqp.Length()/2;
168     if (aNbParts > 1) {  
169       Standard_Boolean bCond;
170       GeomAbs_SurfaceType aST1, aST2;
171       aST1 = myHS1->Surface().GetType();
172       aST2 = myHS2->Surface().GetType();
173       //
174       bCond=Standard_False;
175       if (aST1==GeomAbs_Plane) {
176         if (aST2==GeomAbs_SurfaceOfExtrusion || 
177             aST2==GeomAbs_SurfaceOfRevolution) {//+zft
178           bCond=!bCond;
179         }
180       }
181       else if (aST2==GeomAbs_Plane) {
182         if (aST1==GeomAbs_SurfaceOfExtrusion || 
183             aST1==GeomAbs_SurfaceOfRevolution) {//+zft
184           bCond=!bCond;
185         }
186       }
187       //
188       if (bCond) {
189         Standard_Integer aNb, anIndex, aNbTmp, jx;
190         TColStd_IndexedMapOfInteger aMap;
191         TColStd_SequenceOfReal aSeqTmp;
192         //
193         aNb=seqp.Length();
194         for(i=1; i<=aNb; ++i) {
195           lastp =seqp(i);
196           anIndex=(Standard_Integer)lastp;
197           if (!aMap.Contains(anIndex)){
198             aMap.Add(anIndex);
199             aSeqTmp.Append(lastp);
200           }
201           else {
202             aNbTmp=aSeqTmp.Length();
203             aSeqTmp.Remove(aNbTmp);
204           }
205         }
206         //
207         seqp.Clear();
208         //
209         aNb=aSeqTmp.Length()/2;
210         for(i=1; i<=aNb;++i) {
211           jx=2*i;
212           firstp=aSeqTmp(jx-1);
213           lastp =aSeqTmp(jx);
214           seqp.Append(firstp);
215           seqp.Append(lastp);
216         }
217       }//if (bCond) {
218     }
219     done = Standard_True;
220     return;
221   }// else if(typl == IntPatch_Walking)  {
222   //
223   //-----------------------------------------------------------
224   else if (typl != IntPatch_Restriction)  {
225     seqp.Clear();
226     //
227     Handle(IntPatch_GLine)& GLine =  *((Handle(IntPatch_GLine) *)&L);
228     //
229     if(typl == IntPatch_Circle || typl == IntPatch_Ellipse) { 
230       TreatCircle(L, Tol);
231       done=Standard_True;
232       return;
233     }
234     //----------------------------
235     Standard_Boolean intrvtested;
236     Standard_Real u1,v1,u2,v2;
237     //
238     nbvtx = GeomInt_LineTool::NbVertex(L);
239     intrvtested = Standard_False;
240     for(i=1; i<nbvtx; ++i) { 
241       firstp = GeomInt_LineTool::Vertex(L,i).ParameterOnLine();
242       lastp =  GeomInt_LineTool::Vertex(L,i+1).ParameterOnLine();
243       if(Abs(firstp-lastp)>Precision::PConfusion()) {
244         intrvtested = Standard_True;
245         const Standard_Real pmid = (firstp+lastp)*0.5;
246         gp_Pnt Pmid;
247         GLinePoint(typl, GLine, pmid, Pmid);
248         //
249         Parameters(myHS1,myHS2,Pmid,u1,v1,u2,v2);
250         Recadre(myHS1,myHS2,u1,v1,u2,v2);
251         const TopAbs_State in1 = myDom1->Classify(gp_Pnt2d(u1,v1),Tol);
252         if(in1 !=  TopAbs_OUT) { 
253           const TopAbs_State in2 = myDom2->Classify(gp_Pnt2d(u2,v2),Tol);
254           if(in2 != TopAbs_OUT) { 
255             seqp.Append(firstp);
256             seqp.Append(lastp);
257           }
258         }
259       }
260     }
261     //
262     if (!intrvtested) {
263       // Keep a priori. A point 2d on each
264       // surface is required to make the decision. Will be done in the caller
265       seqp.Append(GeomInt_LineTool::FirstParameter(L));
266       seqp.Append(GeomInt_LineTool::LastParameter(L));
267     }
268     //
269     done =Standard_True;
270     return;
271   } // else if (typl != IntPatch_Restriction)  { 
272
273   done = Standard_False;
274   seqp.Clear();
275   nbvtx = GeomInt_LineTool::NbVertex(L);
276   if (nbvtx == 0) { // Keep a priori. Point 2d is required on each
277                     // surface to make the decision. Will be done in the caller
278     seqp.Append(GeomInt_LineTool::FirstParameter(L));
279     seqp.Append(GeomInt_LineTool::LastParameter(L));
280     done = Standard_True;
281     return;
282   }
283
284   GeomInt_SequenceOfParameterAndOrientation seqpss;
285   TopAbs_Orientation or1=TopAbs_FORWARD,or2=TopAbs_FORWARD;
286
287   for (i=1; i<=nbvtx; i++)  {
288     const IntPatch_Point& thevtx = GeomInt_LineTool::Vertex(L,i);
289     const Standard_Real prm = thevtx.ParameterOnLine();
290     if (thevtx.IsOnDomS1())    {
291       switch (thevtx.TransitionLineArc1().TransitionType())      {
292         case IntSurf_In:        or1 = TopAbs_FORWARD; break;  
293         case IntSurf_Out:       or1 = TopAbs_REVERSED; break;  
294         case IntSurf_Touch:     or1 = TopAbs_INTERNAL; break;  
295         case IntSurf_Undecided: or1 = TopAbs_INTERNAL; break;  
296       }
297     }
298     else {
299       or1 = TopAbs_INTERNAL;
300     }
301     
302     if (thevtx.IsOnDomS2())    {
303       switch (thevtx.TransitionLineArc2().TransitionType())      {
304         case IntSurf_In:        or2 = TopAbs_FORWARD; break;
305         case IntSurf_Out:       or2 = TopAbs_REVERSED; break;
306         case IntSurf_Touch:     or2 = TopAbs_INTERNAL; break;
307         case IntSurf_Undecided: or2 = TopAbs_INTERNAL; break;
308       }
309     }
310     else {
311       or2 = TopAbs_INTERNAL;
312     }
313     //
314     const Standard_Integer nbinserted = seqpss.Length();
315     Standard_Boolean inserted = Standard_False;
316     for (Standard_Integer j=1; j<=nbinserted;j++)    {
317       if (Abs(prm-seqpss(j).Parameter()) <= Tol)      {
318         // accumulate
319         GeomInt_ParameterAndOrientation& valj = seqpss.ChangeValue(j);
320         if (or1 != TopAbs_INTERNAL) {
321           if (valj.Orientation1() != TopAbs_INTERNAL) {
322             if (or1 != valj.Orientation1()) {
323               valj.SetOrientation1(TopAbs_INTERNAL);
324             }
325           }
326           else {
327             valj.SetOrientation1(or1);
328           }
329         }
330         
331         if (or2 != TopAbs_INTERNAL) {
332           if (valj.Orientation2() != TopAbs_INTERNAL) {
333             if (or2 != valj.Orientation2()) {
334               valj.SetOrientation2(TopAbs_INTERNAL);
335             }
336           }
337           else {
338             valj.SetOrientation2(or2);
339           }
340         }         
341         inserted = Standard_True;
342         break;
343       }
344       
345       if (prm < seqpss(j).Parameter()-Tol ) {
346         // insert before position j
347         seqpss.InsertBefore(j,GeomInt_ParameterAndOrientation(prm,or1,or2));
348         inserted = Standard_True;
349         break;
350       }
351       
352     }
353     if (!inserted) {
354       seqpss.Append(GeomInt_ParameterAndOrientation(prm,or1,or2));
355     }
356   }
357
358   // determine the state at the beginning of line
359   Standard_Boolean trim = Standard_False;
360   Standard_Boolean dansS1 = Standard_False;
361   Standard_Boolean dansS2 = Standard_False;
362
363   nbvtx = seqpss.Length();
364   for (i=1; i<= nbvtx; i++)  {
365     or1 = seqpss(i).Orientation1();
366     if (or1 != TopAbs_INTERNAL)    {
367       trim = Standard_True;
368       dansS1 = (or1 != TopAbs_FORWARD);
369       break;
370     }
371   }
372   
373   if (i > nbvtx)  {
374     Standard_Real U,V;
375     for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ )    {
376       if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS1() )      {
377         GeomInt_LineTool::Vertex(L,i).ParametersOnS1(U,V);
378         gp_Pnt2d PPCC(U,V);
379         if (myDom1->Classify(PPCC,Tol) == TopAbs_OUT) {
380           done = Standard_True;
381           return;
382         }
383         break;
384       }
385     }
386     dansS1 = Standard_True; // Keep in doubt
387   }
388   //
389   for (i=1; i<= nbvtx; i++)  {
390     or2 = seqpss(i).Orientation2();
391     if (or2 != TopAbs_INTERNAL)    {
392       trim = Standard_True;
393       dansS2 = (or2 != TopAbs_FORWARD);
394       break;
395     }
396   }
397   
398   if (i > nbvtx)  {
399     Standard_Real U,V;
400     for (i=1; i<=GeomInt_LineTool::NbVertex(L); i++ )    {
401       if (!GeomInt_LineTool::Vertex(L,i).IsOnDomS2() )      {
402         GeomInt_LineTool::Vertex(L,i).ParametersOnS2(U,V);
403         if (myDom2->Classify(gp_Pnt2d(U,V),Tol) == TopAbs_OUT) {
404           done = Standard_True;
405           return;
406         }
407         break;
408       }
409     }
410     dansS2 = Standard_True; //  Keep in doubt
411   }
412
413   if (!trim) { // necessarily dansS1 == dansS2 == Standard_True
414     seqp.Append(GeomInt_LineTool::FirstParameter(L));
415     seqp.Append(GeomInt_LineTool::LastParameter(L));
416     done = Standard_True;
417     return;
418   }
419
420   // sequence seqpss is peeled to create valid ends 
421   // and store them in seqp(2*i+1) and seqp(2*i+2)
422   Standard_Real thefirst = GeomInt_LineTool::FirstParameter(L);
423   Standard_Real thelast = GeomInt_LineTool::LastParameter(L);
424   firstp = thefirst;
425
426   for (i=1; i<=nbvtx; i++)  {
427     or1 = seqpss(i).Orientation1(); 
428     or2 = seqpss(i).Orientation2(); 
429     if (dansS1 && dansS2)    {
430       if (or1 == TopAbs_REVERSED){
431         dansS1 = Standard_False;
432       }
433       
434       if (or2 == TopAbs_REVERSED){
435         dansS2 = Standard_False;
436       }
437       if (!dansS1 || !dansS2)      {
438         lastp = seqpss(i).Parameter();
439         Standard_Real stofirst = Max(firstp, thefirst);
440         Standard_Real stolast  = Min(lastp,  thelast) ;
441
442         if (stolast > stofirst) {
443           seqp.Append(stofirst);
444           seqp.Append(stolast);
445         }
446         if (lastp > thelast) {
447           break;
448         }
449       }
450     }
451     else    {
452       if (dansS1)      {
453         if (or1 == TopAbs_REVERSED) {
454           dansS1 = Standard_False;
455         }
456       }
457       else      {
458         if (or1 == TopAbs_FORWARD){
459           dansS1 = Standard_True;
460         }
461       }
462       if (dansS2) {
463         if (or2 == TopAbs_REVERSED) {
464           dansS2 = Standard_False;
465         }
466       }
467       else {
468         if (or2 == TopAbs_FORWARD){
469           dansS2 = Standard_True;
470         }
471       }
472       if (dansS1 && dansS2){
473         firstp = seqpss(i).Parameter();
474       }
475     }
476   }
477   //
478   // finally to add
479   if (dansS1 && dansS2)  {
480     lastp  = thelast;
481     firstp = Max(firstp,thefirst);
482     if (lastp > firstp) {
483       seqp.Append(firstp);
484       seqp.Append(lastp);
485     }
486   }
487   done = Standard_True;
488 }
489 //=======================================================================
490 //function : Recadre
491 //purpose  : 
492 //=======================================================================
493 void Recadre(const Handle(GeomAdaptor_HSurface)& myHS1,
494              const Handle(GeomAdaptor_HSurface)& myHS2,
495              Standard_Real& u1,
496              Standard_Real& v1,
497              Standard_Real& u2,
498              Standard_Real& v2)
499
500   Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
501   const GeomAbs_SurfaceType typs1 = myHS1->GetType();
502   switch (typs1)
503   { 
504     case GeomAbs_Cylinder:
505     case GeomAbs_Cone:
506     case GeomAbs_Sphere: 
507     { 
508       myHS1IsUPeriodic = Standard_True;
509       myHS1IsVPeriodic = Standard_False;
510       break;
511     }
512     case GeomAbs_Torus:
513     {
514       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
515       break;
516     }
517     default:
518     {
519       //-- Case of periodic biparameters is processed upstream
520       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
521       break;
522     }
523   }
524   Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
525   const GeomAbs_SurfaceType typs2 = myHS2->GetType();
526   switch (typs2)
527   { 
528     case GeomAbs_Cylinder:
529     case GeomAbs_Cone:
530     case GeomAbs_Sphere: 
531     { 
532       myHS2IsUPeriodic = Standard_True;
533       myHS2IsVPeriodic = Standard_False;
534       break;
535     }
536     case GeomAbs_Torus:
537     {
538       myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
539       break;
540     }
541     default:
542     {
543       //-- Case of periodic biparameters is processed upstream
544       myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
545       break;
546     }
547   }
548   if(myHS1IsUPeriodic) {
549     const Standard_Real lmf = M_PI+M_PI; //-- myHS1->UPeriod();
550     const Standard_Real f = myHS1->FirstUParameter();
551     const Standard_Real l = myHS1->LastUParameter();
552     while(u1 < f) { u1+=lmf; } 
553     while(u1 > l) { u1-=lmf; }
554   }
555   if(myHS1IsVPeriodic) {
556     const Standard_Real lmf = M_PI+M_PI; //-- myHS1->VPeriod(); 
557     const Standard_Real f = myHS1->FirstVParameter();
558     const Standard_Real l = myHS1->LastVParameter();
559     while(v1 < f) { v1+=lmf; } 
560     while(v1 > l) { v1-=lmf; }
561   }
562   if(myHS2IsUPeriodic) { 
563     const Standard_Real lmf = M_PI+M_PI; //-- myHS2->UPeriod();
564     const Standard_Real f = myHS2->FirstUParameter();
565     const Standard_Real l = myHS2->LastUParameter();
566     while(u2 < f) { u2+=lmf; } 
567     while(u2 > l) { u2-=lmf; }
568   }
569   if(myHS2IsVPeriodic) { 
570     const Standard_Real lmf = M_PI+M_PI; //-- myHS2->VPeriod();
571     const Standard_Real f = myHS2->FirstVParameter();
572     const Standard_Real l = myHS2->LastVParameter();
573     while(v2 < f) { v2+=lmf; } 
574     while(v2 > l) { v2-=lmf; }
575   }
576 }
577 //=======================================================================
578 //function : Parameters
579 //purpose  : 
580 //=======================================================================
581 void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
582                 const Handle(GeomAdaptor_HSurface)& myHS2,
583                 const gp_Pnt& Ptref,
584                 Standard_Real& U1,
585                 Standard_Real& V1,
586                 Standard_Real& U2,
587                 Standard_Real& V2)
588 {
589   Parameters(myHS1, Ptref, U1, V1);
590   Parameters(myHS2, Ptref, U2, V2);
591 }
592 //=======================================================================
593 //function : Parameter
594 //purpose  : 
595 //=======================================================================
596 void Parameters(const Handle(GeomAdaptor_HSurface)& myHS1,
597                 const gp_Pnt& Ptref,
598                 Standard_Real& U1,
599                 Standard_Real& V1)
600 {
601   IntSurf_Quadric quad1;
602   //
603   switch (myHS1->Surface().GetType())  {
604     case GeomAbs_Plane:    
605       quad1.SetValue(myHS1->Surface().Plane()); 
606       break;
607     case GeomAbs_Cylinder: 
608       quad1.SetValue(myHS1->Surface().Cylinder()); 
609       break;
610     case GeomAbs_Cone:     
611       quad1.SetValue(myHS1->Surface().Cone()); 
612       break;
613     case GeomAbs_Sphere:   
614       quad1.SetValue(myHS1->Surface().Sphere()); 
615       break;
616     case GeomAbs_Torus:
617       quad1.SetValue(myHS1->Surface().Torus()); 
618       break;
619     default: 
620       Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
621   }
622   quad1.Parameters(Ptref,U1,V1);
623 }
624
625 //=======================================================================
626 //function : GLinePoint
627 //purpose  : 
628 //=======================================================================
629 void GLinePoint(const IntPatch_IType typl,
630                 const Handle(IntPatch_GLine)& GLine,
631                 const Standard_Real aT,
632                 gp_Pnt& aP)
633 {
634   switch (typl) {
635     case IntPatch_Lin:       
636     aP = ElCLib::Value(aT, GLine->Line()); 
637     break;
638   case IntPatch_Circle:    
639     aP = ElCLib::Value(aT, GLine->Circle()); 
640     break;
641   case IntPatch_Ellipse:   
642     aP = ElCLib::Value(aT, GLine->Ellipse()); 
643     break;
644   case IntPatch_Hyperbola: 
645     aP = ElCLib::Value(aT, GLine->Hyperbola()); 
646     break;
647   case IntPatch_Parabola:  
648     aP = ElCLib::Value(aT, GLine->Parabola()); 
649     break;
650   default:
651     Standard_ConstructionError::Raise("IntTools_LineConstructor::Parameters");
652   }
653 }
654
655 //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
656 //
657 //=======================================================================
658 //class    : IntTools_RealWithFlag
659 //purpose  : 
660 //=======================================================================
661 class IntTools_RealWithFlag {
662  public:
663   IntTools_RealWithFlag() : 
664     myValue(-99.), myFlag(1) 
665   {
666   };
667   //
668   ~IntTools_RealWithFlag() {
669   };
670   //
671   void SetValue(const Standard_Real aT) {
672     myValue=aT;
673   };
674   //
675   Standard_Real Value() const {
676     return myValue;
677   }
678   //
679   void SetFlag(const Standard_Integer aFlag) {
680     myFlag=aFlag;
681   };
682   //
683   Standard_Integer Flag() const {
684     return myFlag;
685   }
686   //
687   Standard_Boolean operator < (const IntTools_RealWithFlag& aOther) {
688     return myValue<aOther.myValue;
689   }
690   //
691  protected:
692   Standard_Real myValue;
693   Standard_Integer myFlag;
694 };
695 //------------
696 static 
697   void SortShell(const Standard_Integer, 
698                  IntTools_RealWithFlag *); 
699 static
700   void RejectDuplicates(Standard_Integer& aNbVtx, 
701                         IntTools_RealWithFlag *pVtx, 
702                         Standard_Real aTolPrm);
703 static
704   void RejectNearBeacons(Standard_Integer& aNbVtx, 
705                          IntTools_RealWithFlag *pVtx, 
706                          Standard_Real aTolPC1,
707                          const GeomAbs_SurfaceType aTS1,
708                          const GeomAbs_SurfaceType aTS2); 
709 static
710   Standard_Real AdjustOnPeriod(const Standard_Real aTr,
711                                const Standard_Real aPeriod);
712
713 static
714   Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine,
715                                      const IntPatch_IType aType,
716                                      const Standard_Real aTol3D);
717 //
718 //=======================================================================
719 //function : TreatCircle
720 //purpose  : 
721 //=======================================================================
722 void IntTools_LineConstructor::TreatCircle(const Handle(IntPatch_Line)& aLine,
723                                            const Standard_Real aTol)
724 {  
725   Standard_Boolean bRejected;
726   IntPatch_IType aType;
727   //
728   aType=aLine->ArcType();
729   Handle(IntPatch_GLine)& aGLine=*((Handle(IntPatch_GLine) *)&aLine);
730   //
731   bRejected=RejectMicroCircle(aGLine, aType, aTol);
732   if (bRejected) {
733     return;
734   }
735   //----------------------------------------
736   Standard_Boolean bFound;
737   Standard_Integer aNbVtx, aNbVtxWas, i;
738   Standard_Real aTolPC, aT, aT1, aT2, aTmid, aTwoPI, aTolPC1;
739   Standard_Real aU1, aV1, aU2, aV2;
740   TopAbs_State aIn1, aIn2;
741   GeomAbs_SurfaceType aTS1, aTS2;
742   gp_Pnt aPmid;
743   gp_Pnt2d aP2D;
744   IntTools_RealWithFlag *pVtx;
745   //-------------------------------------1
746   aTwoPI=M_PI+M_PI;
747   aTolPC=Precision::PConfusion();
748   aNbVtxWas=GeomInt_LineTool::NbVertex(aLine);
749   
750   aNbVtx=aNbVtxWas+2;
751   //-------------------------------------2
752   aTS1=myHS1->GetType();
753   aTS2=myHS2->GetType();
754   //
755   // About the value aTolPC1=1000.*aTolPC,
756   // see IntPatch_GLine.cxx, line:398
757   // for more details;
758   aTolPC1=1000.*aTolPC; 
759   //-------------------------------------
760   //
761   pVtx=new IntTools_RealWithFlag [aNbVtx];
762   //
763   pVtx[0].SetValue(0.);
764   pVtx[1].SetValue(aTwoPI);
765   //
766   for(i=1; i<=aNbVtxWas; ++i) {
767     aT=GeomInt_LineTool::Vertex(aLine, i).ParameterOnLine();
768     aT=AdjustOnPeriod(aT, aTwoPI);
769     pVtx[i+1].SetValue(aT);
770   }
771   //
772   SortShell(aNbVtx, pVtx);
773   //
774   RejectNearBeacons(aNbVtx, pVtx, aTolPC1, aTS1, aTS2);
775   //
776   RejectDuplicates(aNbVtx, pVtx, aTolPC);
777   //
778   if ((aType==IntPatch_Circle || aType==IntPatch_Ellipse)&& aNbVtx>2) { // zz
779     bFound=Standard_False;
780     for(i=1; i<=aNbVtxWas; ++i) {
781       aT=GeomInt_LineTool::Vertex(aLine, i).ParameterOnLine();
782       if (fabs(aT) < aTolPC1 || fabs(aT-aTwoPI) < aTolPC1) {
783         bFound=!bFound;
784         break;
785       }
786     }
787     if (!bFound) {
788       aT=pVtx[1].Value()+aTwoPI;
789       pVtx[aNbVtx-1].SetValue(aT);
790       //
791       for(i=0; i<aNbVtx; ++i) { 
792         aT=pVtx[i+1].Value();
793         pVtx[i].SetValue(aT);
794       }
795       --aNbVtx;
796     }
797   }
798   //
799   for(i=0; i<aNbVtx-1; ++i) { 
800     aT1=pVtx[i].Value();
801     aT2=pVtx[i+1].Value();
802     aTmid=(aT1+aT2)*0.5;
803     GLinePoint(aType, aGLine, aTmid, aPmid);
804     //
805     Parameters(myHS1, myHS2, aPmid, aU1, aV1, aU2, aV2);
806     Recadre(myHS1, myHS2, aU1, aV1, aU2, aV2);
807     //
808     aP2D.SetCoord(aU1, aV1);
809     aIn1=myDom1->Classify(aP2D, aTol);
810     if(aIn1 !=  TopAbs_OUT) { 
811       aP2D.SetCoord(aU2, aV2);
812       aIn2=myDom2->Classify(aP2D, aTol);
813       if(aIn2 != TopAbs_OUT) { 
814         seqp.Append(aT1);
815         seqp.Append(aT2);
816       }
817     }
818   }
819   //
820   delete [] pVtx;
821 }
822 //=======================================================================
823 //function : RejectNearBeacons
824 //purpose  : Reject the thickenings near the beacon points (if exist)
825 //           The gifts, made by sweep algo.  
826 //           chl/930/B5 B8 C2 C5 E2 E5 E8 F2 G8 H2 H5 H8
827 //=======================================================================
828 void RejectNearBeacons(Standard_Integer& aNbVtx, 
829                        IntTools_RealWithFlag *pVtx, 
830                        Standard_Real aTolPC1,
831                        const GeomAbs_SurfaceType aTS1,
832                        const GeomAbs_SurfaceType aTS2) 
833 {
834   Standard_Integer i, j, iBcn;
835   Standard_Real aT, aBcn[2];
836   //
837   if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) {
838     aBcn[0]=0.5*M_PI;
839     aBcn[1]=1.5*M_PI;
840     //
841     for (j=0; j<2; ++j) {
842       iBcn=-1;
843       for(i=0; i<aNbVtx; ++i) {
844         aT=pVtx[i].Value();
845         if (aT==aBcn[j]) {
846           iBcn=i;
847           break;
848         }
849       }
850       //
851       if (iBcn<0) {
852         // The beacon is not found
853         continue;
854       }
855       //  
856       for(i=0; i<aNbVtx; ++i) {
857         if (i!=iBcn) {
858           aT=pVtx[i].Value();
859           if (fabs(aT-aBcn[j]) < aTolPC1) {
860             pVtx[i].SetFlag(0);
861           }
862         }
863       }
864     }// for (j=0; j<2; ++j) {
865     //------------------------------------------
866     j=0;
867     for(i=0; i<aNbVtx; ++i) {
868       if (pVtx[i].Flag()) {
869         pVtx[j]=pVtx[i];
870         ++j;
871       }
872     }
873     aNbVtx=j;
874   }// if (aTS1==GeomAbs_Cylinder && aTS2==GeomAbs_Cylinder) {
875 }
876
877 //=======================================================================
878 //function : RejectDuplicates
879 //purpose  : 
880 //=======================================================================
881 void RejectDuplicates(Standard_Integer& aNbVtx, 
882                       IntTools_RealWithFlag *pVtx, 
883                       Standard_Real aTolPC) 
884 {
885   Standard_Integer i, j;
886   Standard_Real dX, aT1, aT2; 
887   //
888   for(i=0; i<aNbVtx-1; ++i) {
889     aT2=pVtx[i+1].Value();
890     aT1=pVtx[i].Value();
891     dX=aT2-aT1;
892     if (dX<aTolPC) {
893       pVtx[i+1].SetFlag(0);
894     }
895   }
896   //
897   j=0;
898   for(i=0; i<aNbVtx; ++i) {
899     if (pVtx[i].Flag()) {
900       pVtx[j]=pVtx[i];
901       ++j;
902     }
903   }
904   aNbVtx=j;
905 }
906 //=======================================================================
907 //function : AdjustOnPeriod
908 //purpose  : 
909 //=======================================================================
910 Standard_Real AdjustOnPeriod(const Standard_Real aTr,
911                              const Standard_Real aPeriod)
912 {
913   Standard_Integer k;
914   Standard_Real aT;
915   //
916   aT=aTr;
917   if (aT<0.) {
918     k=-(Standard_Integer)(aT/aPeriod)+1;
919     aT=aT+k*aPeriod;
920   }
921   //
922   if (!(aT>=0. && aT<=aPeriod)) {
923     k=(Standard_Integer)(aT/aPeriod);
924     aT=aT-k*aPeriod;
925   }
926   //
927   return aT;
928 }
929 //=======================================================================
930 //function : RejectMicroCrcles
931 //purpose  : 
932 //=======================================================================
933 Standard_Boolean RejectMicroCircle(const Handle(IntPatch_GLine)& aGLine,
934                                    const IntPatch_IType aType,
935                                    const Standard_Real aTol3D)
936 {
937   Standard_Boolean bRet;
938   Standard_Real aR;
939   //
940   bRet=Standard_False;
941   //
942   if (aType==IntPatch_Circle) {
943     aR=aGLine->Circle().Radius();
944     bRet=(aR<aTol3D);
945   }
946   else if (aType==IntPatch_Ellipse) {
947     aR=aGLine->Ellipse().MajorRadius();
948     bRet=(aR<aTol3D);
949   }
950   return bRet;
951 }
952 //=======================================================================
953 // function: SortShell
954 // purpose : 
955 //=======================================================================
956 void SortShell(const Standard_Integer n, 
957                IntTools_RealWithFlag *a) 
958 {
959   Standard_Integer nd, i, j, l, d=1;
960   IntTools_RealWithFlag x;
961   //
962   while(d<=n) {
963     d*=2;
964   }
965   //
966   while (d) {
967     d=(d-1)/2;
968     //
969     nd=n-d;
970     for (i=0; i<nd; ++i) {
971       j=i;
972     m30:;
973       l=j+d;
974       if (a[l] < a[j]){
975         x=a[j];
976         a[j]=a[l];
977         a[l]=x;
978         j-=d;
979         if (j > -1) goto m30;
980       }//if (a[l] < a[j]){
981     }//for (i=0; i<nd; ++i) 
982   }//while (1)
983 }