0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / Intf / Intf_Tool.cxx
1 // Created on: 1993-06-23
2 // Created by: Didier PIFFAULT
3 // Copyright (c) 1993-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
18 #include <Bnd_Box.hxx>
19 #include <Bnd_Box2d.hxx>
20 #include <ElCLib.hxx>
21 #include <gp_Hypr.hxx>
22 #include <gp_Hypr2d.hxx>
23 #include <gp_Lin.hxx>
24 #include <gp_Lin2d.hxx>
25 #include <gp_Parab.hxx>
26 #include <gp_Parab2d.hxx>
27 #include <gp_Pln.hxx>
28 #include <gp_XY.hxx>
29 #include <IntAna2d_AnaIntersection.hxx>
30 #include <IntAna2d_Conic.hxx>
31 #include <IntAna2d_IntPoint.hxx>
32 #include <IntAna_IntConicQuad.hxx>
33 #include <Intf_Tool.hxx>
34 #include <Precision.hxx>
35 #include <Standard_OutOfRange.hxx>
36
37 //=======================================================================
38 //function : Intf_Tool
39 //purpose  : 
40 //=======================================================================
41 Intf_Tool::Intf_Tool()
42      : nbSeg(0)
43 {
44   memset (beginOnCurve, 0, sizeof (beginOnCurve));
45   memset (bord, 0, sizeof (bord));
46   memset (xint, 0, sizeof (xint));
47   memset (yint, 0, sizeof (yint));
48   memset (zint, 0, sizeof (zint));
49   memset (parint, 0, sizeof (parint));
50 }
51
52 //=======================================================================
53 //function : Lin2dBox
54 //purpose  : 
55 //=======================================================================
56
57 void  Intf_Tool::Lin2dBox(const gp_Lin2d& L2d, 
58                          const Bnd_Box2d& domain, 
59                          Bnd_Box2d& boxLin)
60 {
61   nbSeg=0;
62   boxLin.SetVoid();
63   if        (domain.IsWhole()) {
64     boxLin.Set(L2d.Location(), L2d.Direction());
65     boxLin.Add(L2d.Direction().Reversed());
66     nbSeg=1;
67     beginOnCurve[0]=-Precision::Infinite();
68     endOnCurve[0]=Precision::Infinite();
69     return;
70   }
71   else if   (domain.IsVoid())  return;
72
73   Standard_Real xmin, xmax, ymin, ymax;
74   Standard_Real Xmin=0, Xmax=0, Ymin=0, Ymax=0;
75   Standard_Real parmin=-Precision::Infinite();
76   Standard_Real parmax=Precision::Infinite();
77   Standard_Real parcur, par1,par2;
78   Standard_Boolean xToSet, yToSet;
79
80   domain.Get(xmin,ymin,xmax,ymax);
81
82
83   if      (L2d.Direction().XY().X()>0.) {
84     if (domain.IsOpenXmin()) parmin=-Precision::Infinite();
85     else parmin=(xmin-L2d.Location().XY().X())/L2d.Direction().XY().X();
86     if (domain.IsOpenXmax()) parmax=Precision::Infinite();
87     else parmax=(xmax-L2d.Location().XY().X())/L2d.Direction().XY().X();
88     xToSet=Standard_True;
89   }
90   else if (L2d.Direction().XY().X()<0.) {
91     if (domain.IsOpenXmax()) parmin=-Precision::Infinite();
92     else parmin=(xmax-L2d.Location().XY().X())/L2d.Direction().XY().X();
93     if (domain.IsOpenXmin()) parmax=Precision::Infinite();
94     else parmax=(xmin-L2d.Location().XY().X())/L2d.Direction().XY().X();
95     xToSet=Standard_True;
96   }
97   else { // Parallel to axis  X
98     if (L2d.Location().XY().X()<xmin || xmax<L2d.Location().XY().X())
99       return;
100     Xmin=L2d.Location().XY().X();
101     Xmax=L2d.Location().XY().X();
102     xToSet=Standard_False;
103   }
104
105   if      (L2d.Direction().XY().Y()>0.) {
106     if (domain.IsOpenYmin()) parcur=-Precision::Infinite();
107     else parcur=(ymin-L2d.Location().XY().Y())/L2d.Direction().XY().Y();
108     parmin=Max(parmin, parcur);
109     if (domain.IsOpenYmax()) parcur=Precision::Infinite();
110     else parcur=(ymax-L2d.Location().XY().Y())/L2d.Direction().XY().Y();
111     parmax=Min(parmax, parcur);
112     yToSet=Standard_True;
113   }
114   else if (L2d.Direction().XY().Y()<0.) {
115     if (domain.IsOpenYmax()) parcur=-Precision::Infinite();
116     else parcur=(ymax-L2d.Location().XY().Y())/L2d.Direction().XY().Y();
117     parmin=Max(parmin, parcur);
118     if (domain.IsOpenYmin()) parcur=Precision::Infinite();
119     else parcur=(ymin-L2d.Location().XY().Y())/L2d.Direction().XY().Y();
120     parmax=Min(parmax, parcur);
121     yToSet=Standard_True;
122   }
123   else { // Parallel to axis  Y
124     if (L2d.Location().XY().Y()<ymin || ymax<L2d.Location().XY().Y())
125       return;
126     Ymin=L2d.Location().XY().Y();
127     Ymax=L2d.Location().XY().Y();
128     yToSet=Standard_False;
129   }
130
131   nbSeg++;
132   beginOnCurve[0]=parmin;
133   endOnCurve[0]=parmax;
134
135   if (xToSet) {
136     par1=L2d.Location().XY().X()+parmin*L2d.Direction().XY().X();
137     par2=L2d.Location().XY().X()+parmax*L2d.Direction().XY().X();
138     Xmin=Min(par1, par2);
139     Xmax=Max(par1, par2);
140   }
141
142   if (yToSet) {
143     par1=L2d.Location().XY().Y()+parmin*L2d.Direction().XY().Y();
144     par2=L2d.Location().XY().Y()+parmax*L2d.Direction().XY().Y();
145     Ymin=Min(par1, par2);
146     Ymax=Max(par1, par2);
147   }
148
149   boxLin.Update(Xmin, Ymin, Xmax, Ymax);
150 }
151
152 //=======================================================================
153 //function : Hypr2dBox
154 //purpose  : 
155 //=======================================================================
156
157 void  Intf_Tool::Hypr2dBox(const gp_Hypr2d& theHypr2d, 
158                           const Bnd_Box2d& domain, 
159                           Bnd_Box2d& boxHypr2d)
160 {
161   nbSeg=0;
162   boxHypr2d.SetVoid();
163   if        (domain.IsWhole()) {
164     boxHypr2d.SetWhole();
165     nbSeg=1;
166     beginOnCurve[0]=-Precision::Infinite();
167     endOnCurve[0]=Precision::Infinite();
168     return;
169   }
170   else if   (domain.IsVoid())  return;
171
172   Standard_Integer nbPi=Inters2d(theHypr2d, domain);
173
174   if (nbPi>0) {
175     Standard_Real Xmin, Xmax, Ymin, Ymax;
176
177     domain.Get(Xmax, Ymax, Xmin, Ymin);
178
179     Standard_Integer npi;
180     for (npi=0; npi<nbPi; npi++) {
181       Xmin=Min(Xmin, xint[npi]);
182       Xmax=Max(Xmax, xint[npi]);
183       Ymin=Min(Ymin, yint[npi]);
184       Ymax=Max(Ymax, yint[npi]);
185     }
186     boxHypr2d.Update(Xmin, Ymin, Xmax, Ymax);
187
188     Standard_Integer npj, npk;
189     Standard_Real parmin;
190     for (npi=0; npi<nbPi; npi++) {
191       npk=npi;
192       for (npj=npi+1; npj<nbPi; npj++) 
193         if (parint[npj]<parint[npk]) npk=npj;
194       if (npk!=npi) {
195         parmin=parint[npk];
196         parint[npk]=parint[npi];
197         parint[npi]=parmin;
198         npj=bord[npk];
199         bord[npk]=bord[npi];
200         bord[npi]=npj;
201       }
202     }
203     
204     gp_Pnt2d Pn;
205     gp_Vec2d Tan;
206     Standard_Real sinan=0;
207     Standard_Boolean out=Standard_True;
208
209     for (npi=0; npi<nbPi; npi++) {
210       ElCLib::D1(parint[npi], theHypr2d, Pn, Tan);
211       switch (bord[npi]) {
212       case 1 :
213         sinan=gp_XY(-1.,0.)^Tan.XY();
214         break;
215       case 2 :
216         sinan=gp_XY(0.,-1.)^Tan.XY();
217         break;
218       case 3 :
219         sinan=gp_XY(1.,0.)^Tan.XY();
220         break;
221       case 4 :
222         sinan=gp_XY(0.,1.)^Tan.XY();
223         break;
224       }
225       if (Abs(sinan)>Precision::Angular()) {
226         if (sinan>0.) {
227           out=Standard_False;
228           beginOnCurve[nbSeg]=parint[npi];
229           nbSeg++;
230         }
231         else {
232           if (out) {
233             beginOnCurve[nbSeg]=-Precision::Infinite();
234             nbSeg++;
235           }
236           endOnCurve[nbSeg-1]=parint[npi];
237           out=Standard_True;
238
239           Standard_Integer ipmin;
240           if(beginOnCurve[nbSeg-1] < -10.) ipmin = -10;
241           else ipmin =  (Standard_Integer)(beginOnCurve[nbSeg-1]);
242
243           Standard_Integer ipmax;
244           if(endOnCurve[nbSeg-1] > 10.) ipmax = 10;
245           else ipmax =  (Standard_Integer)(endOnCurve[nbSeg-1]);
246
247           //Standard_Integer ipmin=Max((Standard_Integer)(beginOnCurve[nbSeg-1]),
248                 //                   -10);
249           //Standard_Integer ipmax=Min((Standard_Integer)(endOnCurve[nbSeg-1]), 
250                 //                   10);
251           ipmin=ipmin*10+1;
252           ipmax=ipmax*10-1;
253           Standard_Integer ip, pas=1;
254           for (ip=ipmin; ip<=ipmax; ip+=pas) {
255             boxHypr2d.Add(ElCLib::Value(Standard_Real(ip)/10., theHypr2d));
256             if (Abs(ip)<=10) pas=1;
257             else             pas=10;
258           }
259         }
260       }
261     }
262   }
263   else if (!domain.IsOut(ElCLib::Value(0., theHypr2d))) {
264     boxHypr2d=domain;
265     beginOnCurve[0]=-Precision::Infinite();
266     endOnCurve[0]=Precision::Infinite();
267     nbSeg=1;
268   }
269 }
270
271 //=======================================================================
272 //function : Inters2d
273 //purpose  : 
274 //=======================================================================
275
276 Standard_Integer Intf_Tool::Inters2d(const gp_Hypr2d& theCurv,
277                                     const Bnd_Box2d& Domain)
278 {
279   Standard_Integer nbpi=0;
280   Standard_Integer npi;
281   Standard_Real xmin, xmax, ymin, ymax;
282
283   Domain.Get(xmin,ymin,xmax,ymax);
284
285   if (!Domain.IsOpenYmax()) {
286     gp_Lin2d L1(gp_Pnt2d(0., ymax), gp_Dir2d(-1., 0.));
287     IntAna2d_AnaIntersection Inters1(theCurv, IntAna2d_Conic(L1));
288     if (Inters1.IsDone()) {
289       if (!Inters1.IsEmpty()) {
290         for (npi=1; npi<=Inters1.NbPoints(); npi++) {
291           xint[nbpi]=Inters1.Point(npi).Value().X();
292           if (xmin < xint[nbpi] && xint[nbpi] <=xmax) {
293             yint[nbpi]=ymax;
294             parint[nbpi]=Inters1.Point(npi).ParamOnFirst();
295             bord[nbpi]=1;
296             nbpi++;
297           }
298         }
299       }
300     }
301   }
302
303   if (!Domain.IsOpenXmin()) {
304     gp_Lin2d L2(gp_Pnt2d(xmin, 0.), gp_Dir2d(0., -1.));
305     IntAna2d_AnaIntersection Inters2(theCurv, IntAna2d_Conic(L2));
306     if (Inters2.IsDone()) {
307       if (!Inters2.IsEmpty()) {
308         for (npi=1; npi<=Inters2.NbPoints(); npi++) {
309           yint[nbpi]=Inters2.Point(npi).Value().Y();
310           if (ymin < yint[nbpi] && yint[nbpi] <=ymax) {
311             xint[nbpi]=xmin;
312             parint[nbpi]=Inters2.Point(npi).ParamOnFirst();
313             bord[nbpi]=2;
314             nbpi++;
315           }
316         }
317       }
318     }
319   }
320
321   if (!Domain.IsOpenYmin()) {
322     gp_Lin2d L3(gp_Pnt2d(0., ymin), gp_Dir2d(1., 0.));
323     IntAna2d_AnaIntersection Inters3(theCurv, IntAna2d_Conic(L3));
324     if (Inters3.IsDone()) {
325       if (!Inters3.IsEmpty()) {
326         for (npi=1; npi<=Inters3.NbPoints(); npi++) {
327           xint[nbpi]=Inters3.Point(npi).Value().X();
328           if (xmin <=xint[nbpi] && xint[nbpi] <xmax) {
329             yint[nbpi]=ymin;
330             parint[nbpi]=Inters3.Point(npi).ParamOnFirst();
331             bord[nbpi]=3;
332             nbpi++;
333           }
334         }
335       }
336     }
337   }
338
339   if (!Domain.IsOpenXmax()) {
340     gp_Lin2d L4(gp_Pnt2d(xmax, 0.), gp_Dir2d(0., 1.));
341     IntAna2d_AnaIntersection Inters4(theCurv, IntAna2d_Conic(L4));
342     if (Inters4.IsDone()) {
343       if (!Inters4.IsEmpty()) {
344         for (npi=1; npi<=Inters4.NbPoints(); npi++) {
345           yint[nbpi]=Inters4.Point(npi).Value().Y();
346           if (ymin <= yint[nbpi] && yint[nbpi] < ymax) {
347             xint[nbpi]=xmax;
348             parint[nbpi]=Inters4.Point(npi).ParamOnFirst();
349             bord[nbpi]=4;
350             nbpi++;
351           }
352         }
353       }
354     }
355   }
356   return nbpi;
357 }
358
359 //=======================================================================
360 //function : Parab2dBox
361 //purpose  : 
362 //=======================================================================
363
364 void  Intf_Tool::Parab2dBox(const gp_Parab2d& theParab2d, 
365                            const Bnd_Box2d& domain, 
366                            Bnd_Box2d& boxParab2d)
367 {
368   nbSeg=0;
369   boxParab2d.SetVoid();
370   if        (domain.IsWhole()) {
371     boxParab2d.SetWhole();
372     nbSeg=1;
373     beginOnCurve[0]=-Precision::Infinite();
374     endOnCurve[0]=Precision::Infinite();
375     return;
376   }
377   else if   (domain.IsVoid())  return;
378
379   Standard_Integer nbPi=Inters2d(theParab2d, domain);
380
381   if (nbPi>0) {
382     Standard_Real Xmin, Xmax, Ymin, Ymax;
383
384     domain.Get(Xmax, Ymax, Xmin, Ymin);
385
386     Standard_Integer npi;
387     for (npi=0; npi<nbPi; npi++) {
388       Xmin=Min(Xmin, xint[npi]);
389       Xmax=Max(Xmax, xint[npi]);
390       Ymin=Min(Ymin, yint[npi]);
391       Ymax=Max(Ymax, yint[npi]);
392     }
393     boxParab2d.Update(Xmin, Ymin, Xmax, Ymax);
394
395     Standard_Integer npj, npk;
396     Standard_Real parmin;
397     for (npi=0; npi<nbPi; npi++) {
398       npk=npi;
399       for (npj=npi+1; npj<nbPi; npj++) 
400         if (parint[npj]<parint[npk]) npk=npj;
401       if (npk!=npi) {
402         parmin=parint[npk];
403         parint[npk]=parint[npi];
404         parint[npi]=parmin;
405         npj=bord[npk];
406         bord[npk]=bord[npi];
407         bord[npi]=npj;
408       }
409     }
410     
411     gp_Pnt2d Pn;
412     gp_Vec2d Tan;
413     Standard_Real sinan=0;
414     Standard_Boolean out=Standard_True;
415
416     for (npi=0; npi<nbPi; npi++) {
417       ElCLib::D1(parint[npi], theParab2d, Pn, Tan);
418       switch (bord[npi]) {
419       case 1 :
420         sinan=gp_XY(-1.,0.)^Tan.XY();
421         break;
422       case 2 :
423         sinan=gp_XY(0.,-1.)^Tan.XY();
424         break;
425       case 3 :
426         sinan=gp_XY(1.,0.)^Tan.XY();
427         break;
428       case 4 :
429         sinan=gp_XY(0.,1.)^Tan.XY();
430         break;
431       }
432       if (Abs(sinan)>Precision::Angular()) {
433         if (sinan>0.) {
434           out=Standard_False;
435           beginOnCurve[nbSeg]=parint[npi];
436           nbSeg++;
437         }
438         else {
439           if (out) {
440             beginOnCurve[nbSeg]=-Precision::Infinite();
441             nbSeg++;
442           }
443           endOnCurve[nbSeg-1]=parint[npi];
444           out=Standard_True;
445
446           Standard_Integer ipmin;
447           if(beginOnCurve[nbSeg-1] < -10.) ipmin = -10;
448           else ipmin =  (Standard_Integer)(beginOnCurve[nbSeg-1]);
449
450           Standard_Integer ipmax;
451           if(endOnCurve[nbSeg-1] > 10.) ipmax = 10;
452           else ipmax =  (Standard_Integer)(endOnCurve[nbSeg-1]);
453
454           //Standard_Integer ipmin=Max((Standard_Integer)(beginOnCurve[nbSeg-1]),
455                 //                   -10);
456           //Standard_Integer ipmax=Min((Standard_Integer)(endOnCurve[nbSeg-1]), 
457                 //                   10);
458           ipmin=ipmin*10+1;
459           ipmax=ipmax*10-1;
460           Standard_Integer ip, pas=1;
461           for (ip=ipmin; ip<=ipmax; ip+=pas) {
462             boxParab2d.Add(ElCLib::Value(Standard_Real(ip)/10., theParab2d));
463             if (Abs(ip)<=10) pas=1;
464             else             pas=10;
465           }
466         }
467       }
468     }
469   }
470   else if (!domain.IsOut(ElCLib::Value(0., theParab2d))) {
471     boxParab2d=domain;
472     beginOnCurve[0]=-Precision::Infinite();
473     endOnCurve[0]=Precision::Infinite();
474     nbSeg=1;
475   }
476 }
477
478 //=======================================================================
479 //function : Inters2d
480 //purpose  : 
481 //=======================================================================
482
483 Standard_Integer Intf_Tool::Inters2d(const gp_Parab2d& theCurv,
484                                     const Bnd_Box2d& Domain)
485 {
486   Standard_Integer nbpi=0;
487   Standard_Integer npi;
488   Standard_Real xmin, xmax, ymin, ymax;
489
490   Domain.Get(xmin,ymin,xmax,ymax);
491
492   if (!Domain.IsOpenYmax()) {
493     gp_Lin2d L1(gp_Pnt2d(0., ymax), gp_Dir2d(-1., 0.));
494     IntAna2d_AnaIntersection Inters1(theCurv, IntAna2d_Conic(L1));
495     if (Inters1.IsDone()) {
496       if (!Inters1.IsEmpty()) {
497         for (npi=1; npi<=Inters1.NbPoints(); npi++) {
498           xint[nbpi]=Inters1.Point(npi).Value().X();
499           if (xmin < xint[nbpi] && xint[nbpi] <=xmax) {
500             yint[nbpi]=ymax;
501             parint[nbpi]=Inters1.Point(npi).ParamOnFirst();
502             bord[nbpi]=1;
503             nbpi++;
504           }
505         }
506       }
507     }
508   }
509
510   if (!Domain.IsOpenXmin()) {
511     gp_Lin2d L2(gp_Pnt2d(xmin, 0.), gp_Dir2d(0., -1.));
512     IntAna2d_AnaIntersection Inters2(theCurv, IntAna2d_Conic(L2));
513     if (Inters2.IsDone()) {
514       if (!Inters2.IsEmpty()) {
515         for (npi=1; npi<=Inters2.NbPoints(); npi++) {
516           yint[nbpi]=Inters2.Point(npi).Value().Y();
517           if (ymin < yint[nbpi] && yint[nbpi] <=ymax) {
518             xint[nbpi]=xmin;
519             parint[nbpi]=Inters2.Point(npi).ParamOnFirst();
520             bord[nbpi]=2;
521             nbpi++;
522           }
523         }
524       }
525     }
526   }
527
528   if (!Domain.IsOpenYmin()) {
529     gp_Lin2d L3(gp_Pnt2d(0., ymin), gp_Dir2d(1., 0.));
530     IntAna2d_AnaIntersection Inters3(theCurv, IntAna2d_Conic(L3));
531     if (Inters3.IsDone()) {
532       if (!Inters3.IsEmpty()) {
533         for (npi=1; npi<=Inters3.NbPoints(); npi++) {
534           xint[nbpi]=Inters3.Point(npi).Value().X();
535           if (xmin <=xint[nbpi] && xint[nbpi] <xmax) {
536             yint[nbpi]=ymin;
537             parint[nbpi]=Inters3.Point(npi).ParamOnFirst();
538             bord[nbpi]=3;
539             nbpi++;
540           }
541         }
542       }
543     }
544   }
545
546   if (!Domain.IsOpenXmax()) {
547     gp_Lin2d L4(gp_Pnt2d(xmax, 0.), gp_Dir2d(0., 1.));
548     IntAna2d_AnaIntersection Inters4(theCurv, IntAna2d_Conic(L4));
549     if (Inters4.IsDone()) {
550       if (!Inters4.IsEmpty()) {
551         for (npi=1; npi<=Inters4.NbPoints(); npi++) {
552           yint[nbpi]=Inters4.Point(npi).Value().Y();
553           if (ymin <= yint[nbpi] && yint[nbpi] < ymax) {
554             xint[nbpi]=xmax;
555             parint[nbpi]=Inters4.Point(npi).ParamOnFirst();
556             bord[nbpi]=4;
557             nbpi++;
558           }
559         }
560       }
561     }
562   }
563   return nbpi;
564 }
565
566
567
568
569 //=======================================================================
570 //function : LinBox
571 //purpose  : 
572 //=======================================================================
573
574 void  Intf_Tool::LinBox(const gp_Lin& L, 
575                        const Bnd_Box& domain, 
576                        Bnd_Box& boxLin)
577 {
578   nbSeg=0;
579   boxLin.SetVoid();
580   if        (domain.IsWhole()) {
581     boxLin.Set(L.Location(), L.Direction());
582     boxLin.Add(L.Direction().Reversed());
583     nbSeg=1;
584     beginOnCurve[0]=-Precision::Infinite();
585     endOnCurve[0]=Precision::Infinite();
586     return;
587   }
588   else if   (domain.IsVoid())  return;
589
590   Standard_Real xmin, xmax, ymin, ymax, zmin, zmax;
591   Standard_Real Xmin=0, Xmax=0, Ymin=0, Ymax=0, Zmin=0, Zmax=0;
592   Standard_Real parmin=-Precision::Infinite();
593   Standard_Real parmax=Precision::Infinite();
594   Standard_Real parcur, par1,par2;
595   Standard_Boolean xToSet, yToSet, zToSet;
596
597   domain.Get(xmin,ymin,zmin,xmax,ymax,zmax);
598
599
600   if      (L.Direction().XYZ().X()>0.) {
601     if (domain.IsOpenXmin()) parmin=-Precision::Infinite();
602     else parmin=(xmin-L.Location().XYZ().X())/L.Direction().XYZ().X();
603     if (domain.IsOpenXmax()) parmax=Precision::Infinite();
604     else parmax=(xmax-L.Location().XYZ().X())/L.Direction().XYZ().X();
605     xToSet=Standard_True;
606   }
607   else if (L.Direction().XYZ().X()<0.) {
608     if (domain.IsOpenXmax()) parmin=-Precision::Infinite();
609     else parmin=(xmax-L.Location().XYZ().X())/L.Direction().XYZ().X();
610     if (domain.IsOpenXmin()) parmax=Precision::Infinite();
611     else parmax=(xmin-L.Location().XYZ().X())/L.Direction().XYZ().X();
612     xToSet=Standard_True;
613   }
614   else { // Perpendiculaire a l axe  X
615     if (L.Location().XYZ().X()<xmin || xmax<L.Location().XYZ().X())
616       return;
617     Xmin=L.Location().XYZ().X();
618     Xmax=L.Location().XYZ().X();
619     xToSet=Standard_False;
620   }
621
622   if      (L.Direction().XYZ().Y()>0.) {
623     if (domain.IsOpenYmin()) parcur=-Precision::Infinite();
624     else parcur=(ymin-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
625     parmin=Max(parmin, parcur);
626     if (domain.IsOpenYmax()) parcur=Precision::Infinite();
627     else parcur=(ymax-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
628     parmax=Min(parmax, parcur);
629     yToSet=Standard_True;
630   }
631   else if (L.Direction().XYZ().Y()<0.) {
632     if (domain.IsOpenYmax()) parcur=-Precision::Infinite();
633     else parcur=(ymax-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
634     parmin=Max(parmin, parcur);
635     if (domain.IsOpenYmin()) parcur=Precision::Infinite();
636     else parcur=(ymin-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
637     parmax=Min(parmax, parcur);
638     yToSet=Standard_True;
639   }
640   else { // Perpendiculaire a l axe  Y
641     if (L.Location().XYZ().Y()<ymin || ymax<L.Location().XYZ().Y())
642       return;
643     Ymin=L.Location().XYZ().Y();
644     Ymax=L.Location().XYZ().Y();
645     yToSet=Standard_False;
646   }
647
648   if      (L.Direction().XYZ().Z()>0.) {
649     if (domain.IsOpenZmin()) parcur=-Precision::Infinite();
650     else parcur=(zmin-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
651     parmin=Max(parmin, parcur);
652     if (domain.IsOpenZmax()) parcur=Precision::Infinite();
653     else parcur=(zmax-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
654     parmax=Min(parmax, parcur);
655     zToSet=Standard_True;
656   }
657   else if (L.Direction().XYZ().Z()<0.) {
658     if (domain.IsOpenZmax()) parcur=-Precision::Infinite();
659     else parcur=(zmax-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
660     parmin=Max(parmin, parcur);
661     if (domain.IsOpenZmin()) parcur=Precision::Infinite();
662     else parcur=(zmin-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
663     parmax=Min(parmax, parcur);
664     zToSet=Standard_True;
665   }
666   else { // Perpendicular to axis Z
667     if (L.Location().XYZ().Z()<zmin || zmax<L.Location().XYZ().Z())
668       return;
669     Zmin=L.Location().XYZ().Z();
670     Zmax=L.Location().XYZ().Z();
671     zToSet=Standard_False;
672   }
673
674   nbSeg++;
675   beginOnCurve[0]=parmin;
676   endOnCurve[0]=parmax;
677
678   if (xToSet) {
679     par1=L.Location().XYZ().X()+parmin*L.Direction().XYZ().X();
680     par2=L.Location().XYZ().X()+parmax*L.Direction().XYZ().X();
681     Xmin=Min(par1, par2);
682     Xmax=Max(par1, par2);
683   }
684
685   if (yToSet) {
686     par1=L.Location().XYZ().Y()+parmin*L.Direction().XYZ().Y();
687     par2=L.Location().XYZ().Y()+parmax*L.Direction().XYZ().Y();
688     Ymin=Min(par1, par2);
689     Ymax=Max(par1, par2);
690   }
691
692   if (zToSet) {
693     par1=L.Location().XYZ().Z()+parmin*L.Direction().XYZ().Z();
694     par2=L.Location().XYZ().Z()+parmax*L.Direction().XYZ().Z();
695     Zmin=Min(par1, par2);
696     Zmax=Max(par1, par2);
697   }
698
699   boxLin.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
700 }
701
702 //=======================================================================
703 //function : HyprBox
704 //purpose  : 
705 //=======================================================================
706 void Intf_Tool::HyprBox(const gp_Hypr& theHypr, 
707                         const Bnd_Box& domain, 
708                         Bnd_Box& boxHypr)
709 {
710   nbSeg=0;
711   boxHypr.SetVoid();
712   
713   if (domain.IsWhole()) {
714     boxHypr.SetWhole();
715     nbSeg=1;
716     //beginOnCurve[0]=-Precision::Infinite();
717     //endOnCurve[0]=Precision::Infinite();
718     beginOnCurve[0]=-100.;
719     endOnCurve[0]=100.;
720     return;
721   }
722   else if (domain.IsVoid())  {
723     return;
724   }
725   //
726   Standard_Integer nbPi;
727   //
728   nbPi=Inters3d(theHypr, domain);
729   if (nbPi>0) {
730     Standard_Integer npi;
731     Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
732     //
733     domain.Get(Xmax, Ymax, Zmax, Xmin, Ymin, Zmin);
734     //
735     for (npi=0; npi<nbPi; npi++) {
736       Xmin=Min(Xmin, xint[npi]);
737       Xmax=Max(Xmax, xint[npi]);
738       Ymin=Min(Ymin, yint[npi]);
739       Ymax=Max(Ymax, yint[npi]);
740       Zmin=Min(Zmin, zint[npi]);
741       Zmax=Max(Zmax, yint[npi]);
742     }
743     boxHypr.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
744     //
745     gp_Pnt Pn;
746     gp_Vec Tan;
747     Standard_Real sinan=0;
748     Standard_Boolean out=Standard_True;
749
750     for (npi=0; npi<nbPi; npi++) {
751       ElCLib::D1(parint[npi], theHypr, Pn, Tan);
752       switch (bord[npi]) {
753       case 1 : sinan=gp_XYZ( 1., 0., 0.)*Tan.XYZ(); break;
754       case 2 : sinan=gp_XYZ( 0., 1., 0.)*Tan.XYZ(); break;
755       case 3 : sinan=gp_XYZ( 0., 0., 1.)*Tan.XYZ(); break;
756       case 4 : sinan=gp_XYZ(-1., 0., 0.)*Tan.XYZ(); break;
757       case 5 : sinan=gp_XYZ( 0.,-1., 0.)*Tan.XYZ(); break;
758       case 6 : sinan=gp_XYZ( 0., 0.,-1.)*Tan.XYZ(); break;
759       }
760       if (Abs(sinan)>Precision::Angular()) {
761         if (sinan>0.) {
762           out=Standard_False;
763           beginOnCurve[nbSeg]=parint[npi];
764           //// modified by jgv, 10.11.2009 /////
765           endOnCurve[nbSeg] = 10.;
766           //////////////////////////////////////
767           nbSeg++;
768         }
769         else {
770           if (out) {
771             //modified by NIZNHY-PKV Fri Jul 11 13:59:10 2008f
772             beginOnCurve[nbSeg]=-10.;
773             //beginOnCurve[nbSeg]=-Precision::Infinite();
774             //modified by NIZNHY-PKV Fri Jul 11 13:59:13 2008t
775             nbSeg++;
776           }
777           endOnCurve[nbSeg-1]=parint[npi];
778           out=Standard_True;
779           //
780           //modified by NIZNHY-PKV Fri Jul 11 13:54:54 2008f
781           Standard_Real ipmin, ipmax, ip, pas;
782           //
783           ipmin=-10.;
784           if (beginOnCurve[nbSeg-1]>ipmin) {
785             ipmin=beginOnCurve[nbSeg-1];
786           }
787           ipmax=10.;
788           if (endOnCurve[nbSeg-1]<ipmax) {
789             ipmax=endOnCurve[nbSeg-1];
790           }
791           ipmin=ipmin*10.+1.;
792           ipmax=ipmax*10.-1.;
793           //
794           pas=1.;
795           for (ip=ipmin; ip<=ipmax; ip+=pas) {
796             boxHypr.Add(ElCLib::Value(ip/10., theHypr));
797             pas=10.;
798             if (fabs(ip)<=10.) {
799               pas=1.;
800             }
801           }
802           /*
803           Standard_Integer ipmin=Max((Standard_Integer)(beginOnCurve[nbSeg-1]), -10);
804           Standard_Integer ipmax=Min((Standard_Integer)(endOnCurve[nbSeg-1]),    10);
805           
806           ipmin=ipmin*10+1;
807           ipmax=ipmax*10-1;
808           Standard_Integer ip, pas=1;
809           for (ip=ipmin; ip<=ipmax; ip+=pas) {
810             boxHypr.Add(ElCLib::Value(Standard_Real(ip)/10., theHypr));
811             
812             if (Abs(ip)<=10) {
813               pas=1;
814             }
815             else {
816               pas=10;
817             }
818           }
819           */
820           //modified by NIZNHY-PKV Fri Jul 11 13:55:04 2008t
821         }
822       }
823     }
824   }//if (nbPi>0) {
825   else if (!domain.IsOut(ElCLib::Value(0., theHypr))) {
826     boxHypr=domain;
827     //beginOnCurve[0]=-Precision::Infinite();
828     //endOnCurve[0]=Precision::Infinite();
829     beginOnCurve[0]=-100.;
830     endOnCurve[0]=100.;
831     nbSeg=1;
832   }
833 }
834
835 //=======================================================================
836 //function : Inters3d
837 //purpose  : 
838 //=======================================================================
839
840 Standard_Integer Intf_Tool::Inters3d(const gp_Hypr& theCurv,
841                                     const Bnd_Box& Domain)
842 {
843   Standard_Integer nbpi=0;
844   Standard_Integer npi;
845   Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
846
847   Domain.Get(xmin, ymin, zmin, xmax, ymax, zmax);
848
849   if (!Domain.IsOpenXmin()) {
850     IntAna_IntConicQuad Inters1(theCurv, 
851       gp_Pln(1., 0., 0., -xmin),
852       Precision::Angular());
853     if (Inters1.IsDone()) {
854       if (!Inters1.IsInQuadric()) {
855         for (npi=1; npi<=Inters1.NbPoints(); npi++) {
856           yint[nbpi]=Inters1.Point(npi).Y();
857           zint[nbpi]=Inters1.Point(npi).Z();
858           if (ymin <=yint[nbpi] && yint[nbpi] < ymax &&
859             zmin <=zint[nbpi] && zint[nbpi] < zmax) {
860               xint[nbpi]=xmin;
861               parint[nbpi]=Inters1.ParamOnConic(npi);
862               bord[nbpi]=1;
863               nbpi++;
864           }
865         }
866       }
867     }
868   }
869
870   if (!Domain.IsOpenYmin()) {
871     IntAna_IntConicQuad Inters1(theCurv, 
872       gp_Pln( 0., 1., 0., -ymin),
873       Precision::Angular());
874     if (Inters1.IsDone()) {
875       if (!Inters1.IsInQuadric()) {
876         for (npi=1; npi<=Inters1.NbPoints(); npi++) {
877           xint[nbpi]=Inters1.Point(npi).X();
878           zint[nbpi]=Inters1.Point(npi).Z();
879           if (xmin < xint[nbpi] && xint[nbpi] <=xmax &&
880             zmin <=zint[nbpi] && zint[nbpi] < zmax) {
881               yint[nbpi]=ymin;
882               parint[nbpi]=Inters1.ParamOnConic(npi);
883               bord[nbpi]=2;
884               nbpi++;
885           }
886         }
887       }
888     }
889   }
890
891   if (!Domain.IsOpenZmin()) {
892     IntAna_IntConicQuad Inters1(theCurv, 
893       gp_Pln( 0., 0., 1., -zmin),
894       Precision::Angular());
895     if (Inters1.IsDone()) {
896       if (!Inters1.IsInQuadric()) {
897         for (npi=1; npi<=Inters1.NbPoints(); npi++) {
898           xint[nbpi]=Inters1.Point(npi).X();
899           yint[nbpi]=Inters1.Point(npi).Y();
900           if (xmin < xint[nbpi] && xint[nbpi] <=xmax &&
901             ymin < yint[nbpi] && yint[nbpi] <=ymax) {
902               zint[nbpi]=zmin;
903               parint[nbpi]=Inters1.ParamOnConic(npi);
904               bord[nbpi]=3;
905               nbpi++;
906           }
907         }
908       }
909     }
910   }
911
912   if (!Domain.IsOpenXmax()) {
913     IntAna_IntConicQuad Inters1(theCurv, 
914       gp_Pln(-1., 0., 0., xmax),
915       Precision::Angular());
916     if (Inters1.IsDone()) {
917       if (!Inters1.IsInQuadric()) {
918         for (npi=1; npi<=Inters1.NbPoints(); npi++) {
919           yint[nbpi]=Inters1.Point(npi).Y();
920           zint[nbpi]=Inters1.Point(npi).Z();
921           if (ymin < yint[nbpi] && yint[nbpi] <=ymax &&
922             zmin < zint[nbpi] && zint[nbpi] <=zmax) {
923               xint[nbpi]=xmax;
924               parint[nbpi]=Inters1.ParamOnConic(npi);
925               bord[nbpi]=4;
926               nbpi++;
927           }
928         }
929       }
930     }
931   }
932
933   if (!Domain.IsOpenYmax()) {
934     IntAna_IntConicQuad Inters1(theCurv, 
935       gp_Pln( 0.,-1., 0., ymax),
936       Precision::Angular());
937     if (Inters1.IsDone()) {
938       if (!Inters1.IsInQuadric()) {
939         for (npi=1; npi<=Inters1.NbPoints(); npi++) {
940           xint[nbpi]=Inters1.Point(npi).X();
941           zint[nbpi]=Inters1.Point(npi).Z();
942           if (xmin <=xint[nbpi] && xint[nbpi] < xmax &&
943             zmin < zint[nbpi] && zint[nbpi] <=zmax) {
944               yint[nbpi]=ymax;
945               parint[nbpi]=Inters1.ParamOnConic(npi);
946               bord[nbpi]=5;
947               nbpi++;
948           }
949         }
950       }
951     }
952   }
953
954   if (!Domain.IsOpenZmax()) {
955     IntAna_IntConicQuad Inters1(theCurv, 
956       gp_Pln( 0., 0.,-1., zmax),
957       Precision::Angular());
958     if (Inters1.IsDone()) {
959       if (!Inters1.IsInQuadric()) {
960         for (npi=1; npi<=Inters1.NbPoints(); npi++) {
961           xint[nbpi]=Inters1.Point(npi).X();
962           yint[nbpi]=Inters1.Point(npi).Y();
963           if (xmin <=xint[nbpi] && xint[nbpi] < xmax &&
964             ymin <=yint[nbpi] && yint[nbpi] < ymax) {
965               zint[nbpi]=zmax;
966               parint[nbpi]=Inters1.ParamOnConic(npi);
967               bord[nbpi]=6;
968               nbpi++;
969           }
970         }
971       }
972     }
973   }
974
975   Standard_Integer aNbDiffPoints = nbpi;
976
977   //Sort parint and check if parint contains several
978   //matched values. If that is true they will be deleted.
979   for(Standard_Integer i = nbpi - 1; i > 0 ; i--)
980   {
981     for(Standard_Integer j = 0; j < i; j++)
982     {
983       if(parint[i] <= parint[j])
984       {
985         std::swap (parint[i], parint[j]);
986         std::swap (zint[i], zint[j]);
987         std::swap (yint[i], yint[j]);
988         std::swap (xint[i], xint[j]);
989         std::swap (bord[i], bord[j]);
990       }
991
992       if((i < nbpi - 1) && IsEqual(parint[i], parint[i+1]))
993       {
994         aNbDiffPoints--;
995         for(Standard_Integer k = i; k < aNbDiffPoints; k++)
996         {
997           parint[k] = parint[k+1];
998           zint[k] = zint[k+1];
999           yint[k] = yint[k+1];
1000           xint[k] = xint[k+1];
1001           bord[k] = bord[k+1];
1002         }
1003       }
1004     }
1005   }
1006
1007   return aNbDiffPoints;
1008 }
1009
1010
1011 //=======================================================================
1012 //function : ParabBox
1013 //purpose  : 
1014 //=======================================================================
1015
1016 void  Intf_Tool::ParabBox(const gp_Parab&, 
1017                          const Bnd_Box& domain, 
1018                          Bnd_Box& boxParab)
1019 {
1020   nbSeg=0;
1021   boxParab.SetVoid();
1022   if        (domain.IsWhole()) {
1023     boxParab.SetWhole();
1024     nbSeg=1;
1025     beginOnCurve[0]=-Precision::Infinite();
1026     endOnCurve[0]=Precision::Infinite();
1027     return;
1028   }
1029   else if   (domain.IsVoid())  return;
1030
1031   
1032 }
1033
1034
1035 //=======================================================================
1036 //function : NbSegments
1037 //purpose  : 
1038 //=======================================================================
1039
1040 Standard_Integer Intf_Tool::NbSegments() const
1041 {
1042   return nbSeg;
1043 }
1044
1045 //=======================================================================
1046 //function : BeginParam
1047 //purpose  : 
1048 //=======================================================================
1049
1050 Standard_Real Intf_Tool::BeginParam(const Standard_Integer SegmentNum) const
1051 {
1052   Standard_OutOfRange_Raise_if(SegmentNum<1 || SegmentNum>nbSeg ,
1053                                "Intf_Tool::BeginParam");
1054   return beginOnCurve[SegmentNum-1];
1055 }
1056
1057 //=======================================================================
1058 //function : EndParam
1059 //purpose  : 
1060 //=======================================================================
1061
1062 Standard_Real Intf_Tool::EndParam(const Standard_Integer SegmentNum) const
1063 {
1064   Standard_OutOfRange_Raise_if(SegmentNum<1 || SegmentNum>nbSeg ,
1065                                "Intf_Tool::EndParam");
1066   return endOnCurve[SegmentNum-1];
1067 }
1068