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 |
41 | Intf_Tool::Intf_Tool() |
42 | : nbSeg(0) |
43 | {} |
44 | |
45 | //======================================================================= |
46 | //function : Lin2dBox |
47 | //purpose : |
48 | //======================================================================= |
49 | |
50 | void 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 | |
150 | void 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 | |
269 | Standard_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 | |
357 | void 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 | |
476 | Standard_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 | |
567 | void 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 | //======================================================================= |
699 | void 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 | |
833 | Standard_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 | |
1009 | void 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 | |
1033 | Standard_Integer Intf_Tool::NbSegments() const |
1034 | { |
1035 | return nbSeg; |
1036 | } |
1037 | |
1038 | //======================================================================= |
1039 | //function : BeginParam |
1040 | //purpose : |
1041 | //======================================================================= |
1042 | |
1043 | Standard_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 | |
1055 | Standard_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 | |