0029915: Porting to VC 2017 : Regressions in Modeling Algorithms on VC 2017
[occt.git] / src / Intf / Intf_Tool.cxx
CommitLineData
b311480e 1// Created on: 1993-06-23
2// Created by: Didier PIFFAULT
3// Copyright (c) 1993-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
42cf5bc1 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>
7fd59977 27#include <gp_Pln.hxx>
42cf5bc1 28#include <gp_XY.hxx>
29#include <IntAna2d_AnaIntersection.hxx>
7fd59977 30#include <IntAna2d_Conic.hxx>
31#include <IntAna2d_IntPoint.hxx>
7fd59977 32#include <IntAna_IntConicQuad.hxx>
42cf5bc1 33#include <Intf_Tool.hxx>
7fd59977 34#include <Precision.hxx>
42cf5bc1 35#include <Standard_OutOfRange.hxx>
7fd59977 36
37//=======================================================================
38//function : Intf_Tool
39//purpose :
40//=======================================================================
7fd59977 41Intf_Tool::Intf_Tool()
42 : nbSeg(0)
43{}
44
45//=======================================================================
46//function : Lin2dBox
47//purpose :
48//=======================================================================
49
50void Intf_Tool::Lin2dBox(const gp_Lin2d& L2d,
51 const Bnd_Box2d& domain,
52 Bnd_Box2d& boxLin)
53{
54 nbSeg=0;
55 boxLin.SetVoid();
56 if (domain.IsWhole()) {
57 boxLin.Set(L2d.Location(), L2d.Direction());
58 boxLin.Add(L2d.Direction().Reversed());
59 nbSeg=1;
60 beginOnCurve[0]=-Precision::Infinite();
61 endOnCurve[0]=Precision::Infinite();
62 return;
63 }
64 else if (domain.IsVoid()) return;
65
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;
72
73 domain.Get(xmin,ymin,xmax,ymax);
74
75
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();
81 xToSet=Standard_True;
82 }
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();
88 xToSet=Standard_True;
89 }
90 else { // Parallel to axis X
91 if (L2d.Location().XY().X()<xmin || xmax<L2d.Location().XY().X())
92 return;
93 Xmin=L2d.Location().XY().X();
94 Xmax=L2d.Location().XY().X();
95 xToSet=Standard_False;
96 }
97
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;
106 }
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;
115 }
116 else { // Parallel to axis Y
117 if (L2d.Location().XY().Y()<ymin || ymax<L2d.Location().XY().Y())
118 return;
119 Ymin=L2d.Location().XY().Y();
120 Ymax=L2d.Location().XY().Y();
121 yToSet=Standard_False;
122 }
123
124 nbSeg++;
125 beginOnCurve[0]=parmin;
126 endOnCurve[0]=parmax;
127
128 if (xToSet) {
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);
133 }
134
135 if (yToSet) {
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);
140 }
141
142 boxLin.Update(Xmin, Ymin, Xmax, Ymax);
143}
144
145//=======================================================================
146//function : Hypr2dBox
147//purpose :
148//=======================================================================
7fd59977 149
150void Intf_Tool::Hypr2dBox(const gp_Hypr2d& theHypr2d,
151 const Bnd_Box2d& domain,
152 Bnd_Box2d& boxHypr2d)
153{
154 nbSeg=0;
155 boxHypr2d.SetVoid();
156 if (domain.IsWhole()) {
157 boxHypr2d.SetWhole();
158 nbSeg=1;
159 beginOnCurve[0]=-Precision::Infinite();
160 endOnCurve[0]=Precision::Infinite();
161 return;
162 }
163 else if (domain.IsVoid()) return;
164
165 Standard_Integer nbPi=Inters2d(theHypr2d, domain);
166
167 if (nbPi>0) {
168 Standard_Real Xmin, Xmax, Ymin, Ymax;
169
170 domain.Get(Xmax, Ymax, Xmin, Ymin);
171
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]);
178 }
179 boxHypr2d.Update(Xmin, Ymin, Xmax, Ymax);
180
181 Standard_Integer npj, npk;
182 Standard_Real parmin;
183 for (npi=0; npi<nbPi; npi++) {
184 npk=npi;
185 for (npj=npi+1; npj<nbPi; npj++)
186 if (parint[npj]<parint[npk]) npk=npj;
187 if (npk!=npi) {
188 parmin=parint[npk];
189 parint[npk]=parint[npi];
190 parint[npi]=parmin;
191 npj=bord[npk];
192 bord[npk]=bord[npi];
193 bord[npi]=npj;
194 }
195 }
196
197 gp_Pnt2d Pn;
198 gp_Vec2d Tan;
199 Standard_Real sinan=0;
200 Standard_Boolean out=Standard_True;
201
202 for (npi=0; npi<nbPi; npi++) {
203 ElCLib::D1(parint[npi], theHypr2d, Pn, Tan);
204 switch (bord[npi]) {
205 case 1 :
206 sinan=gp_XY(-1.,0.)^Tan.XY();
207 break;
208 case 2 :
209 sinan=gp_XY(0.,-1.)^Tan.XY();
210 break;
211 case 3 :
212 sinan=gp_XY(1.,0.)^Tan.XY();
213 break;
214 case 4 :
215 sinan=gp_XY(0.,1.)^Tan.XY();
216 break;
217 }
218 if (Abs(sinan)>Precision::Angular()) {
219 if (sinan>0.) {
220 out=Standard_False;
221 beginOnCurve[nbSeg]=parint[npi];
222 nbSeg++;
223 }
224 else {
225 if (out) {
226 beginOnCurve[nbSeg]=-Precision::Infinite();
227 nbSeg++;
228 }
229 endOnCurve[nbSeg-1]=parint[npi];
230 out=Standard_True;
231
232 Standard_Integer ipmin;
233 if(beginOnCurve[nbSeg-1] < -10.) ipmin = -10;
234 else ipmin = (Standard_Integer)(beginOnCurve[nbSeg-1]);
235
236 Standard_Integer ipmax;
237 if(endOnCurve[nbSeg-1] > 10.) ipmax = 10;
238 else ipmax = (Standard_Integer)(endOnCurve[nbSeg-1]);
239
240 //Standard_Integer ipmin=Max((Standard_Integer)(beginOnCurve[nbSeg-1]),
241 // -10);
242 //Standard_Integer ipmax=Min((Standard_Integer)(endOnCurve[nbSeg-1]),
243 // 10);
244 ipmin=ipmin*10+1;
245 ipmax=ipmax*10-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;
250 else pas=10;
251 }
252 }
253 }
254 }
255 }
256 else if (!domain.IsOut(ElCLib::Value(0., theHypr2d))) {
257 boxHypr2d=domain;
258 beginOnCurve[0]=-Precision::Infinite();
259 endOnCurve[0]=Precision::Infinite();
260 nbSeg=1;
261 }
262}
263
264//=======================================================================
265//function : Inters2d
266//purpose :
267//=======================================================================
268
269Standard_Integer Intf_Tool::Inters2d(const gp_Hypr2d& theCurv,
270 const Bnd_Box2d& Domain)
271{
272 Standard_Integer nbpi=0;
273 Standard_Integer npi;
274 Standard_Real xmin, xmax, ymin, ymax;
275
276 Domain.Get(xmin,ymin,xmax,ymax);
277
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) {
286 yint[nbpi]=ymax;
287 parint[nbpi]=Inters1.Point(npi).ParamOnFirst();
288 bord[nbpi]=1;
289 nbpi++;
290 }
291 }
292 }
293 }
294 }
295
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) {
304 xint[nbpi]=xmin;
305 parint[nbpi]=Inters2.Point(npi).ParamOnFirst();
306 bord[nbpi]=2;
307 nbpi++;
308 }
309 }
310 }
311 }
312 }
313
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) {
322 yint[nbpi]=ymin;
323 parint[nbpi]=Inters3.Point(npi).ParamOnFirst();
324 bord[nbpi]=3;
325 nbpi++;
326 }
327 }
328 }
329 }
330 }
331
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) {
340 xint[nbpi]=xmax;
341 parint[nbpi]=Inters4.Point(npi).ParamOnFirst();
342 bord[nbpi]=4;
343 nbpi++;
344 }
345 }
346 }
347 }
348 }
349 return nbpi;
350}
351
352//=======================================================================
353//function : Parab2dBox
354//purpose :
355//=======================================================================
356
357void Intf_Tool::Parab2dBox(const gp_Parab2d& theParab2d,
358 const Bnd_Box2d& domain,
359 Bnd_Box2d& boxParab2d)
360{
361 nbSeg=0;
362 boxParab2d.SetVoid();
363 if (domain.IsWhole()) {
364 boxParab2d.SetWhole();
365 nbSeg=1;
366 beginOnCurve[0]=-Precision::Infinite();
367 endOnCurve[0]=Precision::Infinite();
368 return;
369 }
370 else if (domain.IsVoid()) return;
371
372 Standard_Integer nbPi=Inters2d(theParab2d, domain);
373
374 if (nbPi>0) {
375 Standard_Real Xmin, Xmax, Ymin, Ymax;
376
377 domain.Get(Xmax, Ymax, Xmin, Ymin);
378
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]);
385 }
386 boxParab2d.Update(Xmin, Ymin, Xmax, Ymax);
387
388 Standard_Integer npj, npk;
389 Standard_Real parmin;
390 for (npi=0; npi<nbPi; npi++) {
391 npk=npi;
392 for (npj=npi+1; npj<nbPi; npj++)
393 if (parint[npj]<parint[npk]) npk=npj;
394 if (npk!=npi) {
395 parmin=parint[npk];
396 parint[npk]=parint[npi];
397 parint[npi]=parmin;
398 npj=bord[npk];
399 bord[npk]=bord[npi];
400 bord[npi]=npj;
401 }
402 }
403
404 gp_Pnt2d Pn;
405 gp_Vec2d Tan;
406 Standard_Real sinan=0;
407 Standard_Boolean out=Standard_True;
408
409 for (npi=0; npi<nbPi; npi++) {
410 ElCLib::D1(parint[npi], theParab2d, Pn, Tan);
411 switch (bord[npi]) {
412 case 1 :
413 sinan=gp_XY(-1.,0.)^Tan.XY();
414 break;
415 case 2 :
416 sinan=gp_XY(0.,-1.)^Tan.XY();
417 break;
418 case 3 :
419 sinan=gp_XY(1.,0.)^Tan.XY();
420 break;
421 case 4 :
422 sinan=gp_XY(0.,1.)^Tan.XY();
423 break;
424 }
425 if (Abs(sinan)>Precision::Angular()) {
426 if (sinan>0.) {
427 out=Standard_False;
428 beginOnCurve[nbSeg]=parint[npi];
429 nbSeg++;
430 }
431 else {
432 if (out) {
433 beginOnCurve[nbSeg]=-Precision::Infinite();
434 nbSeg++;
435 }
436 endOnCurve[nbSeg-1]=parint[npi];
437 out=Standard_True;
438
439 Standard_Integer ipmin;
440 if(beginOnCurve[nbSeg-1] < -10.) ipmin = -10;
441 else ipmin = (Standard_Integer)(beginOnCurve[nbSeg-1]);
442
443 Standard_Integer ipmax;
444 if(endOnCurve[nbSeg-1] > 10.) ipmax = 10;
445 else ipmax = (Standard_Integer)(endOnCurve[nbSeg-1]);
446
447 //Standard_Integer ipmin=Max((Standard_Integer)(beginOnCurve[nbSeg-1]),
448 // -10);
449 //Standard_Integer ipmax=Min((Standard_Integer)(endOnCurve[nbSeg-1]),
450 // 10);
451 ipmin=ipmin*10+1;
452 ipmax=ipmax*10-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;
457 else pas=10;
458 }
459 }
460 }
461 }
462 }
463 else if (!domain.IsOut(ElCLib::Value(0., theParab2d))) {
464 boxParab2d=domain;
465 beginOnCurve[0]=-Precision::Infinite();
466 endOnCurve[0]=Precision::Infinite();
467 nbSeg=1;
468 }
469}
470
471//=======================================================================
472//function : Inters2d
473//purpose :
474//=======================================================================
475
476Standard_Integer Intf_Tool::Inters2d(const gp_Parab2d& theCurv,
477 const Bnd_Box2d& Domain)
478{
479 Standard_Integer nbpi=0;
480 Standard_Integer npi;
481 Standard_Real xmin, xmax, ymin, ymax;
482
483 Domain.Get(xmin,ymin,xmax,ymax);
484
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) {
493 yint[nbpi]=ymax;
494 parint[nbpi]=Inters1.Point(npi).ParamOnFirst();
495 bord[nbpi]=1;
496 nbpi++;
497 }
498 }
499 }
500 }
501 }
502
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) {
511 xint[nbpi]=xmin;
512 parint[nbpi]=Inters2.Point(npi).ParamOnFirst();
513 bord[nbpi]=2;
514 nbpi++;
515 }
516 }
517 }
518 }
519 }
520
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) {
529 yint[nbpi]=ymin;
530 parint[nbpi]=Inters3.Point(npi).ParamOnFirst();
531 bord[nbpi]=3;
532 nbpi++;
533 }
534 }
535 }
536 }
537 }
538
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) {
547 xint[nbpi]=xmax;
548 parint[nbpi]=Inters4.Point(npi).ParamOnFirst();
549 bord[nbpi]=4;
550 nbpi++;
551 }
552 }
553 }
554 }
555 }
556 return nbpi;
557}
558
559
560
561
562//=======================================================================
563//function : LinBox
564//purpose :
565//=======================================================================
566
567void Intf_Tool::LinBox(const gp_Lin& L,
568 const Bnd_Box& domain,
569 Bnd_Box& boxLin)
570{
571 nbSeg=0;
572 boxLin.SetVoid();
573 if (domain.IsWhole()) {
574 boxLin.Set(L.Location(), L.Direction());
575 boxLin.Add(L.Direction().Reversed());
576 nbSeg=1;
577 beginOnCurve[0]=-Precision::Infinite();
578 endOnCurve[0]=Precision::Infinite();
579 return;
580 }
581 else if (domain.IsVoid()) return;
582
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;
589
590 domain.Get(xmin,ymin,zmin,xmax,ymax,zmax);
591
592
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;
599 }
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;
606 }
607 else { // Perpendiculaire a l axe X
608 if (L.Location().XYZ().X()<xmin || xmax<L.Location().XYZ().X())
609 return;
610 Xmin=L.Location().XYZ().X();
611 Xmax=L.Location().XYZ().X();
612 xToSet=Standard_False;
613 }
614
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;
623 }
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;
632 }
633 else { // Perpendiculaire a l axe Y
634 if (L.Location().XYZ().Y()<ymin || ymax<L.Location().XYZ().Y())
635 return;
636 Ymin=L.Location().XYZ().Y();
637 Ymax=L.Location().XYZ().Y();
638 yToSet=Standard_False;
639 }
640
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;
649 }
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;
658 }
659 else { // Perpendicular to axis Z
660 if (L.Location().XYZ().Z()<zmin || zmax<L.Location().XYZ().Z())
661 return;
662 Zmin=L.Location().XYZ().Z();
663 Zmax=L.Location().XYZ().Z();
664 zToSet=Standard_False;
665 }
666
667 nbSeg++;
668 beginOnCurve[0]=parmin;
669 endOnCurve[0]=parmax;
670
671 if (xToSet) {
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);
676 }
677
678 if (yToSet) {
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);
683 }
684
685 if (zToSet) {
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);
690 }
691
692 boxLin.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
693}
694
695//=======================================================================
696//function : HyprBox
697//purpose :
698//=======================================================================
699void Intf_Tool::HyprBox(const gp_Hypr& theHypr,
700 const Bnd_Box& domain,
701 Bnd_Box& boxHypr)
702{
703 nbSeg=0;
704 boxHypr.SetVoid();
705
706 if (domain.IsWhole()) {
707 boxHypr.SetWhole();
708 nbSeg=1;
709 //beginOnCurve[0]=-Precision::Infinite();
710 //endOnCurve[0]=Precision::Infinite();
711 beginOnCurve[0]=-100.;
712 endOnCurve[0]=100.;
713 return;
714 }
715 else if (domain.IsVoid()) {
716 return;
717 }
718 //
719 Standard_Integer nbPi;
720 //
721 nbPi=Inters3d(theHypr, domain);
722 if (nbPi>0) {
723 Standard_Integer npi;
724 Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
725 //
726 domain.Get(Xmax, Ymax, Zmax, Xmin, Ymin, Zmin);
727 //
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]);
735 }
736 boxHypr.Update(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
737 //
7fd59977 738 gp_Pnt Pn;
739 gp_Vec Tan;
740 Standard_Real sinan=0;
741 Standard_Boolean out=Standard_True;
742
743 for (npi=0; npi<nbPi; npi++) {
744 ElCLib::D1(parint[npi], theHypr, Pn, Tan);
745 switch (bord[npi]) {
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;
752 }
753 if (Abs(sinan)>Precision::Angular()) {
754 if (sinan>0.) {
755 out=Standard_False;
756 beginOnCurve[nbSeg]=parint[npi];
757 //// modified by jgv, 10.11.2009 /////
758 endOnCurve[nbSeg] = 10.;
759 //////////////////////////////////////
760 nbSeg++;
761 }
762 else {
763 if (out) {
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
768 nbSeg++;
769 }
770 endOnCurve[nbSeg-1]=parint[npi];
771 out=Standard_True;
772 //
773 //modified by NIZNHY-PKV Fri Jul 11 13:54:54 2008f
774 Standard_Real ipmin, ipmax, ip, pas;
775 //
776 ipmin=-10.;
777 if (beginOnCurve[nbSeg-1]>ipmin) {
778 ipmin=beginOnCurve[nbSeg-1];
779 }
780 ipmax=10.;
781 if (endOnCurve[nbSeg-1]<ipmax) {
782 ipmax=endOnCurve[nbSeg-1];
783 }
784 ipmin=ipmin*10.+1.;
785 ipmax=ipmax*10.-1.;
786 //
787 pas=1.;
788 for (ip=ipmin; ip<=ipmax; ip+=pas) {
789 boxHypr.Add(ElCLib::Value(ip/10., theHypr));
790 pas=10.;
791 if (fabs(ip)<=10.) {
792 pas=1.;
793 }
794 }
795 /*
796 Standard_Integer ipmin=Max((Standard_Integer)(beginOnCurve[nbSeg-1]), -10);
797 Standard_Integer ipmax=Min((Standard_Integer)(endOnCurve[nbSeg-1]), 10);
798
799 ipmin=ipmin*10+1;
800 ipmax=ipmax*10-1;
801 Standard_Integer ip, pas=1;
802 for (ip=ipmin; ip<=ipmax; ip+=pas) {
803 boxHypr.Add(ElCLib::Value(Standard_Real(ip)/10., theHypr));
804
805 if (Abs(ip)<=10) {
806 pas=1;
807 }
808 else {
809 pas=10;
810 }
811 }
812 */
813 //modified by NIZNHY-PKV Fri Jul 11 13:55:04 2008t
814 }
815 }
816 }
817 }//if (nbPi>0) {
818 else if (!domain.IsOut(ElCLib::Value(0., theHypr))) {
819 boxHypr=domain;
820 //beginOnCurve[0]=-Precision::Infinite();
821 //endOnCurve[0]=Precision::Infinite();
822 beginOnCurve[0]=-100.;
823 endOnCurve[0]=100.;
824 nbSeg=1;
825 }
826}
827
828//=======================================================================
829//function : Inters3d
830//purpose :
831//=======================================================================
832
833Standard_Integer Intf_Tool::Inters3d(const gp_Hypr& theCurv,
834 const Bnd_Box& Domain)
835{
836 Standard_Integer nbpi=0;
837 Standard_Integer npi;
838 Standard_Real xmin, ymin, zmin, xmax, ymax, zmax;
839
840 Domain.Get(xmin, ymin, zmin, xmax, ymax, zmax);
841
842 if (!Domain.IsOpenXmin()) {
843 IntAna_IntConicQuad Inters1(theCurv,
b89b1e08 844 gp_Pln(1., 0., 0., -xmin),
845 Precision::Angular());
7fd59977 846 if (Inters1.IsDone()) {
847 if (!Inters1.IsInQuadric()) {
b89b1e08 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) {
853 xint[nbpi]=xmin;
854 parint[nbpi]=Inters1.ParamOnConic(npi);
855 bord[nbpi]=1;
856 nbpi++;
857 }
858 }
7fd59977 859 }
860 }
861 }
862
863 if (!Domain.IsOpenYmin()) {
864 IntAna_IntConicQuad Inters1(theCurv,
b89b1e08 865 gp_Pln( 0., 1., 0., -ymin),
866 Precision::Angular());
7fd59977 867 if (Inters1.IsDone()) {
868 if (!Inters1.IsInQuadric()) {
b89b1e08 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) {
874 yint[nbpi]=ymin;
875 parint[nbpi]=Inters1.ParamOnConic(npi);
876 bord[nbpi]=2;
877 nbpi++;
878 }
879 }
7fd59977 880 }
881 }
882 }
883
884 if (!Domain.IsOpenZmin()) {
885 IntAna_IntConicQuad Inters1(theCurv,
b89b1e08 886 gp_Pln( 0., 0., 1., -zmin),
887 Precision::Angular());
7fd59977 888 if (Inters1.IsDone()) {
889 if (!Inters1.IsInQuadric()) {
b89b1e08 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) {
895 zint[nbpi]=zmin;
896 parint[nbpi]=Inters1.ParamOnConic(npi);
897 bord[nbpi]=3;
898 nbpi++;
899 }
900 }
7fd59977 901 }
902 }
903 }
904
905 if (!Domain.IsOpenXmax()) {
906 IntAna_IntConicQuad Inters1(theCurv,
b89b1e08 907 gp_Pln(-1., 0., 0., xmax),
908 Precision::Angular());
7fd59977 909 if (Inters1.IsDone()) {
910 if (!Inters1.IsInQuadric()) {
b89b1e08 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) {
916 xint[nbpi]=xmax;
917 parint[nbpi]=Inters1.ParamOnConic(npi);
918 bord[nbpi]=4;
919 nbpi++;
920 }
921 }
7fd59977 922 }
923 }
924 }
925
926 if (!Domain.IsOpenYmax()) {
927 IntAna_IntConicQuad Inters1(theCurv,
b89b1e08 928 gp_Pln( 0.,-1., 0., ymax),
929 Precision::Angular());
7fd59977 930 if (Inters1.IsDone()) {
931 if (!Inters1.IsInQuadric()) {
b89b1e08 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) {
937 yint[nbpi]=ymax;
938 parint[nbpi]=Inters1.ParamOnConic(npi);
939 bord[nbpi]=5;
940 nbpi++;
941 }
942 }
7fd59977 943 }
944 }
945 }
946
947 if (!Domain.IsOpenZmax()) {
948 IntAna_IntConicQuad Inters1(theCurv,
b89b1e08 949 gp_Pln( 0., 0.,-1., zmax),
950 Precision::Angular());
7fd59977 951 if (Inters1.IsDone()) {
952 if (!Inters1.IsInQuadric()) {
b89b1e08 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) {
958 zint[nbpi]=zmax;
959 parint[nbpi]=Inters1.ParamOnConic(npi);
960 bord[nbpi]=6;
961 nbpi++;
962 }
963 }
7fd59977 964 }
965 }
966 }
b89b1e08 967
968 Standard_Integer aNbDiffPoints = nbpi;
969
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--)
973 {
974 for(Standard_Integer j = 0; j < i; j++)
975 {
976 if(parint[i] <= parint[j])
977 {
04e93070 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]);
b89b1e08 983 }
984
985 if((i < nbpi - 1) && IsEqual(parint[i], parint[i+1]))
986 {
04e93070 987 aNbDiffPoints--;
988 for(Standard_Integer k = i; k < aNbDiffPoints; k++)
b89b1e08 989 {
04e93070 990 parint[k] = parint[k+1];
991 zint[k] = zint[k+1];
992 yint[k] = yint[k+1];
993 xint[k] = xint[k+1];
994 bord[k] = bord[k+1];
b89b1e08 995 }
b89b1e08 996 }
997 }
998 }
999
1000 return aNbDiffPoints;
7fd59977 1001}
1002
1003
1004//=======================================================================
1005//function : ParabBox
1006//purpose :
1007//=======================================================================
1008
1009void Intf_Tool::ParabBox(const gp_Parab&,
1010 const Bnd_Box& domain,
1011 Bnd_Box& boxParab)
1012{
1013 nbSeg=0;
1014 boxParab.SetVoid();
1015 if (domain.IsWhole()) {
1016 boxParab.SetWhole();
1017 nbSeg=1;
1018 beginOnCurve[0]=-Precision::Infinite();
1019 endOnCurve[0]=Precision::Infinite();
1020 return;
1021 }
1022 else if (domain.IsVoid()) return;
1023
1024
1025}
1026
1027
1028//=======================================================================
1029//function : NbSegments
1030//purpose :
1031//=======================================================================
1032
1033Standard_Integer Intf_Tool::NbSegments() const
1034{
1035 return nbSeg;
1036}
1037
1038//=======================================================================
1039//function : BeginParam
1040//purpose :
1041//=======================================================================
1042
1043Standard_Real Intf_Tool::BeginParam(const Standard_Integer SegmentNum) const
1044{
1045 Standard_OutOfRange_Raise_if(SegmentNum<1 || SegmentNum>nbSeg ,
1046 "Intf_Tool::BeginParam");
1047 return beginOnCurve[SegmentNum-1];
1048}
1049
1050//=======================================================================
1051//function : EndParam
1052//purpose :
1053//=======================================================================
1054
1055Standard_Real Intf_Tool::EndParam(const Standard_Integer SegmentNum) const
1056{
1057 Standard_OutOfRange_Raise_if(SegmentNum<1 || SegmentNum>nbSeg ,
1058 "Intf_Tool::EndParam");
1059 return endOnCurve[SegmentNum-1];
1060}
1061