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
6 // This file is part of Open CASCADE Technology software library.
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.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <Bnd_Box.hxx>
19 #include <Bnd_Box2d.hxx>
21 #include <gp_Hypr.hxx>
22 #include <gp_Hypr2d.hxx>
24 #include <gp_Lin2d.hxx>
25 #include <gp_Parab.hxx>
26 #include <gp_Parab2d.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>
37 //=======================================================================
38 //function : Intf_Tool
40 //=======================================================================
41 Intf_Tool::Intf_Tool()
45 //=======================================================================
48 //=======================================================================
50 void Intf_Tool::Lin2dBox(const gp_Lin2d& L2d,
51 const Bnd_Box2d& domain,
56 if (domain.IsWhole()) {
57 boxLin.Set(L2d.Location(), L2d.Direction());
58 boxLin.Add(L2d.Direction().Reversed());
60 beginOnCurve[0]=-Precision::Infinite();
61 endOnCurve[0]=Precision::Infinite();
64 else if (domain.IsVoid()) return;
66 Standard_Real xmin, xmax, ymin, ymax;
67 Standard_Real Xmin=0, Xmax=0, Ymin=0, Ymax=0;
68 Standard_Real parmin=-Precision::Infinite();
69 Standard_Real parmax=Precision::Infinite();
70 Standard_Real parcur, par1,par2;
71 Standard_Boolean xToSet, yToSet;
73 domain.Get(xmin,ymin,xmax,ymax);
76 if (L2d.Direction().XY().X()>0.) {
77 if (domain.IsOpenXmin()) parmin=-Precision::Infinite();
78 else parmin=(xmin-L2d.Location().XY().X())/L2d.Direction().XY().X();
79 if (domain.IsOpenXmax()) parmax=Precision::Infinite();
80 else parmax=(xmax-L2d.Location().XY().X())/L2d.Direction().XY().X();
83 else if (L2d.Direction().XY().X()<0.) {
84 if (domain.IsOpenXmax()) parmin=-Precision::Infinite();
85 else parmin=(xmax-L2d.Location().XY().X())/L2d.Direction().XY().X();
86 if (domain.IsOpenXmin()) parmax=Precision::Infinite();
87 else parmax=(xmin-L2d.Location().XY().X())/L2d.Direction().XY().X();
90 else { // Parallel to axis X
91 if (L2d.Location().XY().X()<xmin || xmax<L2d.Location().XY().X())
93 Xmin=L2d.Location().XY().X();
94 Xmax=L2d.Location().XY().X();
95 xToSet=Standard_False;
98 if (L2d.Direction().XY().Y()>0.) {
99 if (domain.IsOpenYmin()) parcur=-Precision::Infinite();
100 else parcur=(ymin-L2d.Location().XY().Y())/L2d.Direction().XY().Y();
101 parmin=Max(parmin, parcur);
102 if (domain.IsOpenYmax()) parcur=Precision::Infinite();
103 else parcur=(ymax-L2d.Location().XY().Y())/L2d.Direction().XY().Y();
104 parmax=Min(parmax, parcur);
105 yToSet=Standard_True;
107 else if (L2d.Direction().XY().Y()<0.) {
108 if (domain.IsOpenYmax()) parcur=-Precision::Infinite();
109 else parcur=(ymax-L2d.Location().XY().Y())/L2d.Direction().XY().Y();
110 parmin=Max(parmin, parcur);
111 if (domain.IsOpenYmin()) parcur=Precision::Infinite();
112 else parcur=(ymin-L2d.Location().XY().Y())/L2d.Direction().XY().Y();
113 parmax=Min(parmax, parcur);
114 yToSet=Standard_True;
116 else { // Parallel to axis Y
117 if (L2d.Location().XY().Y()<ymin || ymax<L2d.Location().XY().Y())
119 Ymin=L2d.Location().XY().Y();
120 Ymax=L2d.Location().XY().Y();
121 yToSet=Standard_False;
125 beginOnCurve[0]=parmin;
126 endOnCurve[0]=parmax;
129 par1=L2d.Location().XY().X()+parmin*L2d.Direction().XY().X();
130 par2=L2d.Location().XY().X()+parmax*L2d.Direction().XY().X();
131 Xmin=Min(par1, par2);
132 Xmax=Max(par1, par2);
136 par1=L2d.Location().XY().Y()+parmin*L2d.Direction().XY().Y();
137 par2=L2d.Location().XY().Y()+parmax*L2d.Direction().XY().Y();
138 Ymin=Min(par1, par2);
139 Ymax=Max(par1, par2);
142 boxLin.Update(Xmin, Ymin, Xmax, Ymax);
145 //=======================================================================
146 //function : Hypr2dBox
148 //=======================================================================
150 void Intf_Tool::Hypr2dBox(const gp_Hypr2d& theHypr2d,
151 const Bnd_Box2d& domain,
152 Bnd_Box2d& boxHypr2d)
156 if (domain.IsWhole()) {
157 boxHypr2d.SetWhole();
159 beginOnCurve[0]=-Precision::Infinite();
160 endOnCurve[0]=Precision::Infinite();
163 else if (domain.IsVoid()) return;
165 Standard_Integer nbPi=Inters2d(theHypr2d, domain);
168 Standard_Real Xmin, Xmax, Ymin, Ymax;
170 domain.Get(Xmax, Ymax, Xmin, Ymin);
172 Standard_Integer npi;
173 for (npi=0; npi<nbPi; npi++) {
174 Xmin=Min(Xmin, xint[npi]);
175 Xmax=Max(Xmax, xint[npi]);
176 Ymin=Min(Ymin, yint[npi]);
177 Ymax=Max(Ymax, yint[npi]);
179 boxHypr2d.Update(Xmin, Ymin, Xmax, Ymax);
181 Standard_Integer npj, npk;
182 Standard_Real parmin;
183 for (npi=0; npi<nbPi; npi++) {
185 for (npj=npi+1; npj<nbPi; npj++)
186 if (parint[npj]<parint[npk]) npk=npj;
189 parint[npk]=parint[npi];
199 Standard_Real sinan=0;
200 Standard_Boolean out=Standard_True;
202 for (npi=0; npi<nbPi; npi++) {
203 ElCLib::D1(parint[npi], theHypr2d, Pn, Tan);
206 sinan=gp_XY(-1.,0.)^Tan.XY();
209 sinan=gp_XY(0.,-1.)^Tan.XY();
212 sinan=gp_XY(1.,0.)^Tan.XY();
215 sinan=gp_XY(0.,1.)^Tan.XY();
218 if (Abs(sinan)>Precision::Angular()) {
221 beginOnCurve[nbSeg]=parint[npi];
226 beginOnCurve[nbSeg]=-Precision::Infinite();
229 endOnCurve[nbSeg-1]=parint[npi];
232 Standard_Integer ipmin;
233 if(beginOnCurve[nbSeg-1] < -10.) ipmin = -10;
234 else ipmin = (Standard_Integer)(beginOnCurve[nbSeg-1]);
236 Standard_Integer ipmax;
237 if(endOnCurve[nbSeg-1] > 10.) ipmax = 10;
238 else ipmax = (Standard_Integer)(endOnCurve[nbSeg-1]);
240 //Standard_Integer ipmin=Max((Standard_Integer)(beginOnCurve[nbSeg-1]),
242 //Standard_Integer ipmax=Min((Standard_Integer)(endOnCurve[nbSeg-1]),
246 Standard_Integer ip, pas=1;
247 for (ip=ipmin; ip<=ipmax; ip+=pas) {
248 boxHypr2d.Add(ElCLib::Value(Standard_Real(ip)/10., theHypr2d));
249 if (Abs(ip)<=10) pas=1;
256 else if (!domain.IsOut(ElCLib::Value(0., theHypr2d))) {
258 beginOnCurve[0]=-Precision::Infinite();
259 endOnCurve[0]=Precision::Infinite();
264 //=======================================================================
265 //function : Inters2d
267 //=======================================================================
269 Standard_Integer Intf_Tool::Inters2d(const gp_Hypr2d& theCurv,
270 const Bnd_Box2d& Domain)
272 Standard_Integer nbpi=0;
273 Standard_Integer npi;
274 Standard_Real xmin, xmax, ymin, ymax;
276 Domain.Get(xmin,ymin,xmax,ymax);
278 if (!Domain.IsOpenYmax()) {
279 gp_Lin2d L1(gp_Pnt2d(0., ymax), gp_Dir2d(-1., 0.));
280 IntAna2d_AnaIntersection Inters1(theCurv, IntAna2d_Conic(L1));
281 if (Inters1.IsDone()) {
282 if (!Inters1.IsEmpty()) {
283 for (npi=1; npi<=Inters1.NbPoints(); npi++) {
284 xint[nbpi]=Inters1.Point(npi).Value().X();
285 if (xmin < xint[nbpi] && xint[nbpi] <=xmax) {
287 parint[nbpi]=Inters1.Point(npi).ParamOnFirst();
296 if (!Domain.IsOpenXmin()) {
297 gp_Lin2d L2(gp_Pnt2d(xmin, 0.), gp_Dir2d(0., -1.));
298 IntAna2d_AnaIntersection Inters2(theCurv, IntAna2d_Conic(L2));
299 if (Inters2.IsDone()) {
300 if (!Inters2.IsEmpty()) {
301 for (npi=1; npi<=Inters2.NbPoints(); npi++) {
302 yint[nbpi]=Inters2.Point(npi).Value().Y();
303 if (ymin < yint[nbpi] && yint[nbpi] <=ymax) {
305 parint[nbpi]=Inters2.Point(npi).ParamOnFirst();
314 if (!Domain.IsOpenYmin()) {
315 gp_Lin2d L3(gp_Pnt2d(0., ymin), gp_Dir2d(1., 0.));
316 IntAna2d_AnaIntersection Inters3(theCurv, IntAna2d_Conic(L3));
317 if (Inters3.IsDone()) {
318 if (!Inters3.IsEmpty()) {
319 for (npi=1; npi<=Inters3.NbPoints(); npi++) {
320 xint[nbpi]=Inters3.Point(npi).Value().X();
321 if (xmin <=xint[nbpi] && xint[nbpi] <xmax) {
323 parint[nbpi]=Inters3.Point(npi).ParamOnFirst();
332 if (!Domain.IsOpenXmax()) {
333 gp_Lin2d L4(gp_Pnt2d(xmax, 0.), gp_Dir2d(0., 1.));
334 IntAna2d_AnaIntersection Inters4(theCurv, IntAna2d_Conic(L4));
335 if (Inters4.IsDone()) {
336 if (!Inters4.IsEmpty()) {
337 for (npi=1; npi<=Inters4.NbPoints(); npi++) {
338 yint[nbpi]=Inters4.Point(npi).Value().Y();
339 if (ymin <= yint[nbpi] && yint[nbpi] < ymax) {
341 parint[nbpi]=Inters4.Point(npi).ParamOnFirst();
352 //=======================================================================
353 //function : Parab2dBox
355 //=======================================================================
357 void Intf_Tool::Parab2dBox(const gp_Parab2d& theParab2d,
358 const Bnd_Box2d& domain,
359 Bnd_Box2d& boxParab2d)
362 boxParab2d.SetVoid();
363 if (domain.IsWhole()) {
364 boxParab2d.SetWhole();
366 beginOnCurve[0]=-Precision::Infinite();
367 endOnCurve[0]=Precision::Infinite();
370 else if (domain.IsVoid()) return;
372 Standard_Integer nbPi=Inters2d(theParab2d, domain);
375 Standard_Real Xmin, Xmax, Ymin, Ymax;
377 domain.Get(Xmax, Ymax, Xmin, Ymin);
379 Standard_Integer npi;
380 for (npi=0; npi<nbPi; npi++) {
381 Xmin=Min(Xmin, xint[npi]);
382 Xmax=Max(Xmax, xint[npi]);
383 Ymin=Min(Ymin, yint[npi]);
384 Ymax=Max(Ymax, yint[npi]);
386 boxParab2d.Update(Xmin, Ymin, Xmax, Ymax);
388 Standard_Integer npj, npk;
389 Standard_Real parmin;
390 for (npi=0; npi<nbPi; npi++) {
392 for (npj=npi+1; npj<nbPi; npj++)
393 if (parint[npj]<parint[npk]) npk=npj;
396 parint[npk]=parint[npi];
406 Standard_Real sinan=0;
407 Standard_Boolean out=Standard_True;
409 for (npi=0; npi<nbPi; npi++) {
410 ElCLib::D1(parint[npi], theParab2d, Pn, Tan);
413 sinan=gp_XY(-1.,0.)^Tan.XY();
416 sinan=gp_XY(0.,-1.)^Tan.XY();
419 sinan=gp_XY(1.,0.)^Tan.XY();
422 sinan=gp_XY(0.,1.)^Tan.XY();
425 if (Abs(sinan)>Precision::Angular()) {
428 beginOnCurve[nbSeg]=parint[npi];
433 beginOnCurve[nbSeg]=-Precision::Infinite();
436 endOnCurve[nbSeg-1]=parint[npi];
439 Standard_Integer ipmin;
440 if(beginOnCurve[nbSeg-1] < -10.) ipmin = -10;
441 else ipmin = (Standard_Integer)(beginOnCurve[nbSeg-1]);
443 Standard_Integer ipmax;
444 if(endOnCurve[nbSeg-1] > 10.) ipmax = 10;
445 else ipmax = (Standard_Integer)(endOnCurve[nbSeg-1]);
447 //Standard_Integer ipmin=Max((Standard_Integer)(beginOnCurve[nbSeg-1]),
449 //Standard_Integer ipmax=Min((Standard_Integer)(endOnCurve[nbSeg-1]),
453 Standard_Integer ip, pas=1;
454 for (ip=ipmin; ip<=ipmax; ip+=pas) {
455 boxParab2d.Add(ElCLib::Value(Standard_Real(ip)/10., theParab2d));
456 if (Abs(ip)<=10) pas=1;
463 else if (!domain.IsOut(ElCLib::Value(0., theParab2d))) {
465 beginOnCurve[0]=-Precision::Infinite();
466 endOnCurve[0]=Precision::Infinite();
471 //=======================================================================
472 //function : Inters2d
474 //=======================================================================
476 Standard_Integer Intf_Tool::Inters2d(const gp_Parab2d& theCurv,
477 const Bnd_Box2d& Domain)
479 Standard_Integer nbpi=0;
480 Standard_Integer npi;
481 Standard_Real xmin, xmax, ymin, ymax;
483 Domain.Get(xmin,ymin,xmax,ymax);
485 if (!Domain.IsOpenYmax()) {
486 gp_Lin2d L1(gp_Pnt2d(0., ymax), gp_Dir2d(-1., 0.));
487 IntAna2d_AnaIntersection Inters1(theCurv, IntAna2d_Conic(L1));
488 if (Inters1.IsDone()) {
489 if (!Inters1.IsEmpty()) {
490 for (npi=1; npi<=Inters1.NbPoints(); npi++) {
491 xint[nbpi]=Inters1.Point(npi).Value().X();
492 if (xmin < xint[nbpi] && xint[nbpi] <=xmax) {
494 parint[nbpi]=Inters1.Point(npi).ParamOnFirst();
503 if (!Domain.IsOpenXmin()) {
504 gp_Lin2d L2(gp_Pnt2d(xmin, 0.), gp_Dir2d(0., -1.));
505 IntAna2d_AnaIntersection Inters2(theCurv, IntAna2d_Conic(L2));
506 if (Inters2.IsDone()) {
507 if (!Inters2.IsEmpty()) {
508 for (npi=1; npi<=Inters2.NbPoints(); npi++) {
509 yint[nbpi]=Inters2.Point(npi).Value().Y();
510 if (ymin < yint[nbpi] && yint[nbpi] <=ymax) {
512 parint[nbpi]=Inters2.Point(npi).ParamOnFirst();
521 if (!Domain.IsOpenYmin()) {
522 gp_Lin2d L3(gp_Pnt2d(0., ymin), gp_Dir2d(1., 0.));
523 IntAna2d_AnaIntersection Inters3(theCurv, IntAna2d_Conic(L3));
524 if (Inters3.IsDone()) {
525 if (!Inters3.IsEmpty()) {
526 for (npi=1; npi<=Inters3.NbPoints(); npi++) {
527 xint[nbpi]=Inters3.Point(npi).Value().X();
528 if (xmin <=xint[nbpi] && xint[nbpi] <xmax) {
530 parint[nbpi]=Inters3.Point(npi).ParamOnFirst();
539 if (!Domain.IsOpenXmax()) {
540 gp_Lin2d L4(gp_Pnt2d(xmax, 0.), gp_Dir2d(0., 1.));
541 IntAna2d_AnaIntersection Inters4(theCurv, IntAna2d_Conic(L4));
542 if (Inters4.IsDone()) {
543 if (!Inters4.IsEmpty()) {
544 for (npi=1; npi<=Inters4.NbPoints(); npi++) {
545 yint[nbpi]=Inters4.Point(npi).Value().Y();
546 if (ymin <= yint[nbpi] && yint[nbpi] < ymax) {
548 parint[nbpi]=Inters4.Point(npi).ParamOnFirst();
562 //=======================================================================
565 //=======================================================================
567 void Intf_Tool::LinBox(const gp_Lin& L,
568 const Bnd_Box& domain,
573 if (domain.IsWhole()) {
574 boxLin.Set(L.Location(), L.Direction());
575 boxLin.Add(L.Direction().Reversed());
577 beginOnCurve[0]=-Precision::Infinite();
578 endOnCurve[0]=Precision::Infinite();
581 else if (domain.IsVoid()) return;
583 Standard_Real xmin, xmax, ymin, ymax, zmin, zmax;
584 Standard_Real Xmin=0, Xmax=0, Ymin=0, Ymax=0, Zmin=0, Zmax=0;
585 Standard_Real parmin=-Precision::Infinite();
586 Standard_Real parmax=Precision::Infinite();
587 Standard_Real parcur, par1,par2;
588 Standard_Boolean xToSet, yToSet, zToSet;
590 domain.Get(xmin,ymin,zmin,xmax,ymax,zmax);
593 if (L.Direction().XYZ().X()>0.) {
594 if (domain.IsOpenXmin()) parmin=-Precision::Infinite();
595 else parmin=(xmin-L.Location().XYZ().X())/L.Direction().XYZ().X();
596 if (domain.IsOpenXmax()) parmax=Precision::Infinite();
597 else parmax=(xmax-L.Location().XYZ().X())/L.Direction().XYZ().X();
598 xToSet=Standard_True;
600 else if (L.Direction().XYZ().X()<0.) {
601 if (domain.IsOpenXmax()) parmin=-Precision::Infinite();
602 else parmin=(xmax-L.Location().XYZ().X())/L.Direction().XYZ().X();
603 if (domain.IsOpenXmin()) parmax=Precision::Infinite();
604 else parmax=(xmin-L.Location().XYZ().X())/L.Direction().XYZ().X();
605 xToSet=Standard_True;
607 else { // Perpendiculaire a l axe X
608 if (L.Location().XYZ().X()<xmin || xmax<L.Location().XYZ().X())
610 Xmin=L.Location().XYZ().X();
611 Xmax=L.Location().XYZ().X();
612 xToSet=Standard_False;
615 if (L.Direction().XYZ().Y()>0.) {
616 if (domain.IsOpenYmin()) parcur=-Precision::Infinite();
617 else parcur=(ymin-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
618 parmin=Max(parmin, parcur);
619 if (domain.IsOpenYmax()) parcur=Precision::Infinite();
620 else parcur=(ymax-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
621 parmax=Min(parmax, parcur);
622 yToSet=Standard_True;
624 else if (L.Direction().XYZ().Y()<0.) {
625 if (domain.IsOpenYmax()) parcur=-Precision::Infinite();
626 else parcur=(ymax-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
627 parmin=Max(parmin, parcur);
628 if (domain.IsOpenYmin()) parcur=Precision::Infinite();
629 else parcur=(ymin-L.Location().XYZ().Y())/L.Direction().XYZ().Y();
630 parmax=Min(parmax, parcur);
631 yToSet=Standard_True;
633 else { // Perpendiculaire a l axe Y
634 if (L.Location().XYZ().Y()<ymin || ymax<L.Location().XYZ().Y())
636 Ymin=L.Location().XYZ().Y();
637 Ymax=L.Location().XYZ().Y();
638 yToSet=Standard_False;
641 if (L.Direction().XYZ().Z()>0.) {
642 if (domain.IsOpenZmin()) parcur=-Precision::Infinite();
643 else parcur=(zmin-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
644 parmin=Max(parmin, parcur);
645 if (domain.IsOpenZmax()) parcur=Precision::Infinite();
646 else parcur=(zmax-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
647 parmax=Min(parmax, parcur);
648 zToSet=Standard_True;
650 else if (L.Direction().XYZ().Z()<0.) {
651 if (domain.IsOpenZmax()) parcur=-Precision::Infinite();
652 else parcur=(zmax-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
653 parmin=Max(parmin, parcur);
654 if (domain.IsOpenZmin()) parcur=Precision::Infinite();
655 else parcur=(zmin-L.Location().XYZ().Z())/L.Direction().XYZ().Z();
656 parmax=Min(parmax, parcur);
657 zToSet=Standard_True;
659 else { // Perpendicular to axis Z
660 if (L.Location().XYZ().Z()<zmin || zmax<L.Location().XYZ().Z())
662 Zmin=L.Location().XYZ().Z();
663 Zmax=L.Location().XYZ().Z();
664 zToSet=Standard_False;
668 beginOnCurve[0]=parmin;
669 endOnCurve[0]=parmax;
672 par1=L.Location().XYZ().X()+parmin*L.Direction().XYZ().X();
673 par2=L.Location().XYZ().X()+parmax*L.Direction().XYZ().X();
674 Xmin=Min(par1, par2);
675 Xmax=Max(par1, par2);
679 par1=L.Location().XYZ().Y()+parmin*L.Direction().XYZ().Y();
680 par2=L.Location().XYZ().Y()+parmax*L.Direction().XYZ().Y();
681 Ymin=Min(par1, par2);
682 Ymax=Max(par1, par2);
686 par1=L.Location().XYZ().Z()+parmin*L.Direction().XYZ().Z();
687 par2=L.Location().XYZ().Z()+parmax*L.Direction().XYZ().Z();
688 Zmin=Min(par1, par2);
689 Zmax=Max(par1, par2);
692 boxLin.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
695 //=======================================================================
698 //=======================================================================
699 void Intf_Tool::HyprBox(const gp_Hypr& theHypr,
700 const Bnd_Box& domain,
706 if (domain.IsWhole()) {
709 //beginOnCurve[0]=-Precision::Infinite();
710 //endOnCurve[0]=Precision::Infinite();
711 beginOnCurve[0]=-100.;
715 else if (domain.IsVoid()) {
719 Standard_Integer nbPi;
721 nbPi=Inters3d(theHypr, domain);
723 Standard_Integer npi;
724 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
726 domain.Get(Xmax, Ymax, Zmax, Xmin, Ymin, Zmin);
728 for (npi=0; npi<nbPi; npi++) {
729 Xmin=Min(Xmin, xint[npi]);
730 Xmax=Max(Xmax, xint[npi]);
731 Ymin=Min(Ymin, yint[npi]);
732 Ymax=Max(Ymax, yint[npi]);
733 Zmin=Min(Zmin, zint[npi]);
734 Zmax=Max(Zmax, yint[npi]);
736 boxHypr.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
740 Standard_Real sinan=0;
741 Standard_Boolean out=Standard_True;
743 for (npi=0; npi<nbPi; npi++) {
744 ElCLib::D1(parint[npi], theHypr, Pn, Tan);
746 case 1 : sinan=gp_XYZ( 1., 0., 0.)*Tan.XYZ(); break;
747 case 2 : sinan=gp_XYZ( 0., 1., 0.)*Tan.XYZ(); break;
748 case 3 : sinan=gp_XYZ( 0., 0., 1.)*Tan.XYZ(); break;
749 case 4 : sinan=gp_XYZ(-1., 0., 0.)*Tan.XYZ(); break;
750 case 5 : sinan=gp_XYZ( 0.,-1., 0.)*Tan.XYZ(); break;
751 case 6 : sinan=gp_XYZ( 0., 0.,-1.)*Tan.XYZ(); break;
753 if (Abs(sinan)>Precision::Angular()) {
756 beginOnCurve[nbSeg]=parint[npi];
757 //// modified by jgv, 10.11.2009 /////
758 endOnCurve[nbSeg] = 10.;
759 //////////////////////////////////////
764 //modified by NIZNHY-PKV Fri Jul 11 13:59:10 2008f
765 beginOnCurve[nbSeg]=-10.;
766 //beginOnCurve[nbSeg]=-Precision::Infinite();
767 //modified by NIZNHY-PKV Fri Jul 11 13:59:13 2008t
770 endOnCurve[nbSeg-1]=parint[npi];
773 //modified by NIZNHY-PKV Fri Jul 11 13:54:54 2008f
774 Standard_Real ipmin, ipmax, ip, pas;
777 if (beginOnCurve[nbSeg-1]>ipmin) {
778 ipmin=beginOnCurve[nbSeg-1];
781 if (endOnCurve[nbSeg-1]<ipmax) {
782 ipmax=endOnCurve[nbSeg-1];
788 for (ip=ipmin; ip<=ipmax; ip+=pas) {
789 boxHypr.Add(ElCLib::Value(ip/10., theHypr));
796 Standard_Integer ipmin=Max((Standard_Integer)(beginOnCurve[nbSeg-1]), -10);
797 Standard_Integer ipmax=Min((Standard_Integer)(endOnCurve[nbSeg-1]), 10);
801 Standard_Integer ip, pas=1;
802 for (ip=ipmin; ip<=ipmax; ip+=pas) {
803 boxHypr.Add(ElCLib::Value(Standard_Real(ip)/10., theHypr));
813 //modified by NIZNHY-PKV Fri Jul 11 13:55:04 2008t
818 else if (!domain.IsOut(ElCLib::Value(0., theHypr))) {
820 //beginOnCurve[0]=-Precision::Infinite();
821 //endOnCurve[0]=Precision::Infinite();
822 beginOnCurve[0]=-100.;
828 //=======================================================================
829 //function : Inters3d
831 //=======================================================================
833 Standard_Integer Intf_Tool::Inters3d(const gp_Hypr& theCurv,
834 const Bnd_Box& Domain)
836 Standard_Integer nbpi=0;
837 Standard_Integer npi;
838 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
840 Domain.Get(xmin, ymin, zmin, xmax, ymax, zmax);
842 if (!Domain.IsOpenXmin()) {
843 IntAna_IntConicQuad Inters1(theCurv,
844 gp_Pln(1., 0., 0., -xmin),
845 Precision::Angular());
846 if (Inters1.IsDone()) {
847 if (!Inters1.IsInQuadric()) {
848 for (npi=1; npi<=Inters1.NbPoints(); npi++) {
849 yint[nbpi]=Inters1.Point(npi).Y();
850 zint[nbpi]=Inters1.Point(npi).Z();
851 if (ymin <=yint[nbpi] && yint[nbpi] < ymax &&
852 zmin <=zint[nbpi] && zint[nbpi] < zmax) {
854 parint[nbpi]=Inters1.ParamOnConic(npi);
863 if (!Domain.IsOpenYmin()) {
864 IntAna_IntConicQuad Inters1(theCurv,
865 gp_Pln( 0., 1., 0., -ymin),
866 Precision::Angular());
867 if (Inters1.IsDone()) {
868 if (!Inters1.IsInQuadric()) {
869 for (npi=1; npi<=Inters1.NbPoints(); npi++) {
870 xint[nbpi]=Inters1.Point(npi).X();
871 zint[nbpi]=Inters1.Point(npi).Z();
872 if (xmin < xint[nbpi] && xint[nbpi] <=xmax &&
873 zmin <=zint[nbpi] && zint[nbpi] < zmax) {
875 parint[nbpi]=Inters1.ParamOnConic(npi);
884 if (!Domain.IsOpenZmin()) {
885 IntAna_IntConicQuad Inters1(theCurv,
886 gp_Pln( 0., 0., 1., -zmin),
887 Precision::Angular());
888 if (Inters1.IsDone()) {
889 if (!Inters1.IsInQuadric()) {
890 for (npi=1; npi<=Inters1.NbPoints(); npi++) {
891 xint[nbpi]=Inters1.Point(npi).X();
892 yint[nbpi]=Inters1.Point(npi).Y();
893 if (xmin < xint[nbpi] && xint[nbpi] <=xmax &&
894 ymin < yint[nbpi] && yint[nbpi] <=ymax) {
896 parint[nbpi]=Inters1.ParamOnConic(npi);
905 if (!Domain.IsOpenXmax()) {
906 IntAna_IntConicQuad Inters1(theCurv,
907 gp_Pln(-1., 0., 0., xmax),
908 Precision::Angular());
909 if (Inters1.IsDone()) {
910 if (!Inters1.IsInQuadric()) {
911 for (npi=1; npi<=Inters1.NbPoints(); npi++) {
912 yint[nbpi]=Inters1.Point(npi).Y();
913 zint[nbpi]=Inters1.Point(npi).Z();
914 if (ymin < yint[nbpi] && yint[nbpi] <=ymax &&
915 zmin < zint[nbpi] && zint[nbpi] <=zmax) {
917 parint[nbpi]=Inters1.ParamOnConic(npi);
926 if (!Domain.IsOpenYmax()) {
927 IntAna_IntConicQuad Inters1(theCurv,
928 gp_Pln( 0.,-1., 0., ymax),
929 Precision::Angular());
930 if (Inters1.IsDone()) {
931 if (!Inters1.IsInQuadric()) {
932 for (npi=1; npi<=Inters1.NbPoints(); npi++) {
933 xint[nbpi]=Inters1.Point(npi).X();
934 zint[nbpi]=Inters1.Point(npi).Z();
935 if (xmin <=xint[nbpi] && xint[nbpi] < xmax &&
936 zmin < zint[nbpi] && zint[nbpi] <=zmax) {
938 parint[nbpi]=Inters1.ParamOnConic(npi);
947 if (!Domain.IsOpenZmax()) {
948 IntAna_IntConicQuad Inters1(theCurv,
949 gp_Pln( 0., 0.,-1., zmax),
950 Precision::Angular());
951 if (Inters1.IsDone()) {
952 if (!Inters1.IsInQuadric()) {
953 for (npi=1; npi<=Inters1.NbPoints(); npi++) {
954 xint[nbpi]=Inters1.Point(npi).X();
955 yint[nbpi]=Inters1.Point(npi).Y();
956 if (xmin <=xint[nbpi] && xint[nbpi] < xmax &&
957 ymin <=yint[nbpi] && yint[nbpi] < ymax) {
959 parint[nbpi]=Inters1.ParamOnConic(npi);
968 Standard_Integer aNbDiffPoints = nbpi;
970 //Sort parint and check if parint contains several
971 //matched values. If that is true they will be deleted.
972 for(Standard_Integer i = nbpi - 1; i > 0 ; i--)
974 for(Standard_Integer j = 0; j < i; j++)
976 if(parint[i] <= parint[j])
978 std::swap (parint[i], parint[j]);
979 std::swap (zint[i], zint[j]);
980 std::swap (yint[i], yint[j]);
981 std::swap (xint[i], xint[j]);
982 std::swap (bord[i], bord[j]);
985 if((i < nbpi - 1) && IsEqual(parint[i], parint[i+1]))
988 for(Standard_Integer k = i; k < aNbDiffPoints; k++)
990 parint[k] = parint[k+1];
1000 return aNbDiffPoints;
1004 //=======================================================================
1005 //function : ParabBox
1007 //=======================================================================
1009 void Intf_Tool::ParabBox(const gp_Parab&,
1010 const Bnd_Box& domain,
1015 if (domain.IsWhole()) {
1016 boxParab.SetWhole();
1018 beginOnCurve[0]=-Precision::Infinite();
1019 endOnCurve[0]=Precision::Infinite();
1022 else if (domain.IsVoid()) return;
1028 //=======================================================================
1029 //function : NbSegments
1031 //=======================================================================
1033 Standard_Integer Intf_Tool::NbSegments() const
1038 //=======================================================================
1039 //function : BeginParam
1041 //=======================================================================
1043 Standard_Real Intf_Tool::BeginParam(const Standard_Integer SegmentNum) const
1045 Standard_OutOfRange_Raise_if(SegmentNum<1 || SegmentNum>nbSeg ,
1046 "Intf_Tool::BeginParam");
1047 return beginOnCurve[SegmentNum-1];
1050 //=======================================================================
1051 //function : EndParam
1053 //=======================================================================
1055 Standard_Real Intf_Tool::EndParam(const Standard_Integer SegmentNum) const
1057 Standard_OutOfRange_Raise_if(SegmentNum<1 || SegmentNum>nbSeg ,
1058 "Intf_Tool::EndParam");
1059 return endOnCurve[SegmentNum-1];