1 // Created on: 1991-06-24
2 // Created by: Didier PIFFAULT
3 // Copyright (c) -1999 Matra Datavision
4 // Copyright (c) 1991-1999 Matra Datavision
5 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 //
7 // This file is part of Open CASCADE Technology software library.
8 //
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17
18
19 #include <Bnd_Box2d.hxx>
20 #include <gp_Pnt2d.hxx>
21 #include <Intf_InterferencePolygon2d.hxx>
22 #include <Intf_Polygon2d.hxx>
23 #include <Intf_SectionPoint.hxx>
24 #include <Intf_SeqOfSectionPoint.hxx>
25 #include <Intf_SeqOfTangentZone.hxx>
26 #include <Intf_TangentZone.hxx>
27 #include <Precision.hxx>
28 #include <Standard_OutOfRange.hxx>
29 #include <TColStd_ListOfInteger.hxx>
30
31 // Angular precision (sinus) below that value two right segments
32 // are considered as having a potential zone of tangency.
33 namespace
34 {
35 static const Standard_Real PRCANG = Precision::Angular();
36 }
37
38 //=======================================================================
39 //function : Intf_InterferencePolygon2d
40 //purpose : constructor empty
41 //=======================================================================
42
Intf_InterferencePolygon2d()43 Intf_InterferencePolygon2d::Intf_InterferencePolygon2d()
44 : Intf_Interference (Standard_False),
45 oClos (Standard_False),
46 tClos (Standard_False),
47 nbso (0)
48 {}
49
50 //=======================================================================
51 //function : Intf_InterferencePolygon2d
52 //purpose : Constructor of the interference between two Polygon.
53 //=======================================================================
54
Intf_InterferencePolygon2d(const Intf_Polygon2d & Obje1,const Intf_Polygon2d & Obje2)55 Intf_InterferencePolygon2d::Intf_InterferencePolygon2d
56 (const Intf_Polygon2d& Obje1, const Intf_Polygon2d& Obje2)
57 : Intf_Interference (Standard_False),
58 oClos (Standard_False),
59 tClos (Standard_False),
60 nbso (0)
61 {
62 if (!Obje1.Bounding().IsOut(Obje2.Bounding())) {
63 Tolerance=Obje1.DeflectionOverEstimation()+
64 Obje2.DeflectionOverEstimation();
65 if (Tolerance==0.)
66 Tolerance=Epsilon(1000.);
67 nbso=Obje1.NbSegments();
68 oClos=Obje1.Closed();
69 tClos=Obje2.Closed();
70 Interference(Obje1, Obje2);
71 Clean();
72 }
73 }
74
75
76 //=======================================================================
77 //function : Intf_InterferencePolygon2d
78 //purpose : Constructor of the auto interference of a Polygon.
79 //=======================================================================
80
Intf_InterferencePolygon2d(const Intf_Polygon2d & Obje)81 Intf_InterferencePolygon2d::Intf_InterferencePolygon2d
82 (const Intf_Polygon2d& Obje)
83 : Intf_Interference (Standard_True),
84 oClos (Standard_False),
85 tClos (Standard_False),
86 nbso (0)
87 {
88 Tolerance=Obje.DeflectionOverEstimation()*2;
89 if (Tolerance==0.)
90 Tolerance=Epsilon(1000.);
91 oClos=Obje.Closed();
92 tClos=oClos;
93 Interference(Obje);
94 Clean();
95 }
96
97 //=======================================================================
98 //function : Perform
99 //purpose :
100 //=======================================================================
101
Perform(const Intf_Polygon2d & Obje1,const Intf_Polygon2d & Obje2)102 void Intf_InterferencePolygon2d::Perform
103 (const Intf_Polygon2d& Obje1, const Intf_Polygon2d& Obje2)
104 {
105 SelfInterference(Standard_False);
106 if (!Obje1.Bounding().IsOut(Obje2.Bounding())) {
107 Tolerance=Obje1.DeflectionOverEstimation()+
108 Obje2.DeflectionOverEstimation();
109 if (Tolerance==0.)
110 Tolerance=Epsilon(1000.);
111 nbso=Obje1.NbSegments();
112 oClos=Obje1.Closed();
113 tClos=Obje2.Closed();
114 Interference(Obje1, Obje2);
115 Clean();
116 }
117 }
118
119 //=======================================================================
120 //function : Perform
121 //purpose :
122 //=======================================================================
123
Perform(const Intf_Polygon2d & Obje)124 void Intf_InterferencePolygon2d::Perform
125 (const Intf_Polygon2d& Obje)
126 {
127 SelfInterference(Standard_True);
128 Tolerance=Obje.DeflectionOverEstimation()*2;
129 if (Tolerance==0.)
130 Tolerance=Epsilon(1000.);
131 oClos=Obje.Closed();
132 tClos=oClos;
133 Interference(Obje);
134 Clean();
135 }
136
137 //=======================================================================
138 //function : Pnt2dValue
139 //purpose : Give the section point of range Index in the interference.
140 //=======================================================================
141
Pnt2dValue(const Standard_Integer Index) const142 gp_Pnt2d Intf_InterferencePolygon2d::Pnt2dValue
143 (const Standard_Integer Index) const
144 {
145 return gp_Pnt2d((mySPoins(Index)).Pnt().X(),
146 (mySPoins(Index)).Pnt().Y());
147 }
148
149
150 //=======================================================================
151 //function : Interference
152 //purpose :
153 //=======================================================================
154
Interference(const Intf_Polygon2d & Obje1,const Intf_Polygon2d & Obje2)155 void Intf_InterferencePolygon2d::Interference
156 (const Intf_Polygon2d& Obje1,
157 const Intf_Polygon2d& Obje2)
158 {
159 Bnd_Box2d bSO;
160 Bnd_Box2d bST;
161
162 Standard_Integer iObje1, iObje2, n1 = nbso, n2 = Obje2.NbSegments();
163 Standard_Real d1 = Obje1.DeflectionOverEstimation(),
164 d2 = Obje2.DeflectionOverEstimation();
165
166 gp_Pnt2d p1b, p1e, p2b, p2e;
167 for (iObje1=1; iObje1<=n1; iObje1++)
168 {
169 bSO.SetVoid();
170 Obje1.Segment(iObje1,p1b,p1e);
171 bSO.Add(p1b);
172 bSO.Add(p1e);
173 bSO.Enlarge(d1);
174 if (!Obje2.Bounding().IsOut(bSO)) {
175 for (iObje2=1; iObje2<=n2; iObje2++) {
176 bST.SetVoid();
177 Obje2.Segment(iObje2,p2b,p2e);
178 bST.Add(p2b);
179 bST.Add(p2e);
180 bST.Enlarge(d2);
181 if (!bSO.IsOut(bST))
182 Intersect(iObje1, iObje2, p1b, p1e, p2b, p2e);
183 }
184 }
185 }
186 }
187
188 //=======================================================================
189 //function : Interference
190 //purpose :
191 //=======================================================================
192
Interference(const Intf_Polygon2d & Obje)193 void Intf_InterferencePolygon2d::Interference
194 (const Intf_Polygon2d& Obje)
195 {
196 Bnd_Box2d bSO;
197 Bnd_Box2d bST;
198
199 Standard_Integer iObje1, iObje2, n = Obje.NbSegments();
200 Standard_Real d = Obje.DeflectionOverEstimation();
201
202 gp_Pnt2d p1b, p1e, p2b, p2e;
203 for (iObje1=1; iObje1<=n; iObje1++) {
204 bSO.SetVoid();
205 Obje.Segment(iObje1,p1b,p1e);
206 bSO.Add(p1b);
207 bSO.Add(p1e);
208 bSO.Enlarge(d);
209 if (!Obje.Bounding().IsOut(bSO)) {
210 for (iObje2=iObje1+1;iObje2<=n;iObje2++){
211 bST.SetVoid();
212 Obje.Segment(iObje2,p2b,p2e);
213 bST.Add(p2b);
214 bST.Add(p2e);
215 bST.Enlarge(d);
216 if (!bSO.IsOut(bST))
217 Intersect(iObje1, iObje2, p1b, p1e, p2b, p2e);
218 }
219 }
220 }
221 }
222
223
224 //=======================================================================
225 //function : Clean
226 //purpose :
227 //=======================================================================
228
Clean()229 void Intf_InterferencePolygon2d::Clean()
230 {
231
232 // The zones of tangency that concerns only one couple of segments are
233 // conserved if the angle between the segments is less than <PRCANG> and
234 // if there is no real point of intersection EDGE/EDGE:
235 Standard_Integer nbIt=myTZones.Length();
236 Standard_Integer decal=0;
237 Standard_Integer addr1, addr2;
238 Intf_PIType dim1, dim2;
239 Standard_Real par;
240 Standard_Integer tsp, tsps;
241 Standard_Integer lpi, ltz;
242 Standard_Boolean Only1Seg=Standard_False;
243
244 #define PI1 (myTZones(ltz-decal).GetPoint(lpi))
245 #define PI2 (myTZones(ltz-decal).GetPoint(tsp))
246
247 for (ltz=1; ltz<=nbIt; ltz++) {
248 tsp=tsps=0;
249 Standard_Real pr1mi,pr1ma,pr2mi,pr2ma,delta1,delta2;
250 myTZones(ltz-decal).ParamOnFirst(pr1mi,pr1ma);
251 delta1=pr1ma-pr1mi;
252 myTZones(ltz-decal).ParamOnSecond(pr2mi,pr2ma);
253 delta2=pr2ma-pr2mi;
254 if (delta1<1. && delta2<1.) Only1Seg=Standard_True;
255 if (delta1==0. || delta2==0.) Only1Seg=Standard_True;
256
257 for (lpi=1; lpi<=myTZones(ltz-decal).NumberOfPoints(); lpi++) {
258 if (PI1.Incidence()<=PRCANG) {tsp=tsps=0;break;}
259 PI1.InfoFirst(dim1,addr1,par);
260 PI1.InfoSecond(dim2,addr2,par);
261 if (dim1==Intf_EDGE && dim2==Intf_EDGE) {
262 tsps=0;
263 if (tsp>0) {
264 tsp=0;
265 Only1Seg=Standard_False;
266 break;
267 }
268 tsp=lpi;
269 }
270 else if (dim1!=Intf_EXTERNAL && dim2!=Intf_EXTERNAL) {
271 tsps=lpi;
272 }
273 }
274 if (tsp>0) {
275 mySPoins.Append(myTZones(ltz-decal).GetPoint(tsp));
276 myTZones.Remove(ltz-decal);
277 decal++;
278 }
279 else if (Only1Seg && tsps!=0) {
280 mySPoins.Append(myTZones(ltz-decal).GetPoint(tsps));
281 myTZones.Remove(ltz-decal);
282 decal++;
283 }
284 }
285
286
287 // The points of intersection located in the tangency zone are
288 // removed from the list :
289 nbIt=mySPoins.Length();
290 decal=0;
291
292 for (lpi=1; lpi<=nbIt; lpi++) {
293 for (ltz=1; ltz<=myTZones.Length(); ltz++) {
294 if (myTZones(ltz).RangeContains(mySPoins(lpi-decal))) {
295 mySPoins.Remove(lpi-decal);
296 decal++;
297 break;
298 }
299 }
300 }
301 }
302
303
304 //=======================================================================
305 //function : Intersect
306 //purpose :
307 //=======================================================================
308
Intersect(const Standard_Integer iObje1,const Standard_Integer iObje2,const gp_Pnt2d & BegO,const gp_Pnt2d & EndO,const gp_Pnt2d & BegT,const gp_Pnt2d & EndT)309 void Intf_InterferencePolygon2d::Intersect
310 (const Standard_Integer iObje1, const Standard_Integer iObje2,
311 const gp_Pnt2d& BegO, const gp_Pnt2d& EndO,
312 const gp_Pnt2d& BegT, const gp_Pnt2d& EndT)
313 {
314 if(SelfIntf) {
315 if(Abs(iObje1-iObje2)<=1) return; //-- Ajout du 15 jan 98
316 }
317
318 Standard_Integer nbpi=0;
319 Standard_Real parO[8];
320 Standard_Real parT[8];
321 Intf_SeqOfSectionPoint thePi;
322 gp_XY segT =EndT.XY()-BegT.XY();
323 gp_XY segO =EndO.XY()-BegO.XY();
324
325 // If the length of segment is zero, nothing is done
326 Standard_Real lgT =Sqrt(segT*segT);
327 if (lgT<=0.) return;
328 Standard_Real lgO =Sqrt(segO*segO);
329 if (lgO<=0.) return;
330
331 // Direction of parsing of segments
332 Standard_Real sigPS=(segO*segT)>0.0 ? 1.0 : -1.0;
333
334 // Precision of calculation
335 Standard_Real floatgap=Epsilon(lgO+lgT);
336
337 // Angle between two straight lines and radius of interference
338 Standard_Real sinTeta=(segO.CrossMagnitude(segT)/lgO)/lgT;
339 Standard_Real rayIntf=0.;
340 if (sinTeta>0.) rayIntf=Tolerance/sinTeta;
341
342 // Interference <begO> <segT>
343 Standard_Real dbOT=((BegO.XY()-BegT.XY())^segT)/lgT;
344 Standard_Real dbObT=BegO.Distance(BegT);
345 Standard_Real dbOeT=BegO.Distance(EndT);
346 if (Abs(dbOT)<=Tolerance) {
347 if (dbObT<=Tolerance) {
348 nbpi++;
349 parO[nbpi]=0.;parT[nbpi]=0.;
350 thePi.Append(Intf_SectionPoint(BegO,Intf_VERTEX,iObje1,0.,
351 Intf_VERTEX,iObje2,0.,sinTeta));
352 }
353 if (dbOeT<=Tolerance) {
354 nbpi++;
355 parO[nbpi]=0.;parT[nbpi]=1.;
356 thePi.Append(Intf_SectionPoint(BegO,Intf_VERTEX,iObje1,0.,
357 Intf_VERTEX,iObje2+1,0.,sinTeta));
358 }
359 if (dbObT>Tolerance && dbOeT>Tolerance &&
360 dbObT+dbOeT<=(lgT+Tolerance)) {
361 nbpi++;
362 parO[nbpi]=0.;parT[nbpi]=dbObT/lgT;
363 thePi.Append(Intf_SectionPoint(BegO,Intf_VERTEX,iObje1,0.,
364 Intf_EDGE,iObje2,parT[nbpi],sinTeta));
365 }
366 }
367
368 // Interference <endO> <segT>
369 Standard_Real deOT=((EndO.XY()-BegT.XY())^segT)/lgT;
370 Standard_Real deObT=EndO.Distance(BegT);
371 Standard_Real deOeT=EndO.Distance(EndT);
372 if (Abs(deOT)<=Tolerance) {
373 if (deObT<=Tolerance) {
374 nbpi++;
375 parO[nbpi]=1.;parT[nbpi]=0.;
376 thePi.Append(Intf_SectionPoint(EndO,Intf_VERTEX,iObje1+1,0.,
377 Intf_VERTEX,iObje2,0.,sinTeta));
378 }
379 if (deOeT<=Tolerance) {
380 nbpi++;
381 parO[nbpi]=1.;parT[nbpi]=1.;
382 thePi.Append(Intf_SectionPoint(EndO,Intf_VERTEX,iObje1+1,0.,
383 Intf_VERTEX,iObje2+1,0.,sinTeta));
384 }
385 if (deObT>Tolerance && deOeT>Tolerance &&
386 deObT+deOeT<=(lgT+Tolerance)) {
387 nbpi++;
388 parO[nbpi]=1.;parT[nbpi]=deObT/lgT;
389 thePi.Append(Intf_SectionPoint(EndO,Intf_VERTEX,iObje1+1,0.,
390 Intf_EDGE,iObje2,parT[nbpi],sinTeta));
391 }
392 }
393
394 // Interference <begT> <segO>
395 Standard_Real dbTO=((BegT.XY()-BegO.XY())^segO)/lgO;
396 if (Abs(dbTO)<=Tolerance) {
397 if (dbObT>Tolerance && deObT>Tolerance &&
398 dbObT+deObT<=(lgO+Tolerance)) {
399 nbpi++;
400 parO[nbpi]=dbObT/lgO;parT[nbpi]=0.;
401 thePi.Append(Intf_SectionPoint(BegT,Intf_EDGE,iObje1,parO[nbpi],
402 Intf_VERTEX,iObje2,0.,sinTeta));
403 }
404 }
405
406 // Interference <endT> <segO>
407 Standard_Real deTO=((EndT.XY()-BegO.XY())^segO)/lgO;
408 if (Abs(deTO)<=Tolerance) {
409 if (dbOeT>Tolerance && deOeT>Tolerance &&
410 dbOeT+deOeT<=(lgO+Tolerance)) {
411 nbpi++;
412 parO[nbpi]=dbOeT/lgO;parT[nbpi]=1.;
413 thePi.Append(Intf_SectionPoint(EndT,Intf_EDGE,iObje1,parO[nbpi],
414 Intf_VERTEX,iObje2+1,0.,sinTeta));
415 }
416 }
417
418 Standard_Boolean edgeSP=Standard_False;
419 Standard_Real parOSP=0, parTSP=0;
420
421 if (Abs(dbOT-deOT)>floatgap && Abs(dbTO-deTO)>floatgap) {
422 parOSP=dbOT/(dbOT-deOT);
423 parTSP=dbTO/(dbTO-deTO);
424 if (dbOT*deOT<=0. && dbTO*deTO<=0.) {
425 edgeSP=Standard_True;
426 }
427 else if (nbpi==0) return;
428
429 // If there is no interference it is necessary to take the points segment by segment
430 if (nbpi==0 && sinTeta>PRCANG) {
431 nbpi++;
432 parO[nbpi]=parOSP;
433 parT[nbpi]=parTSP;
434 thePi.Append(Intf_SectionPoint(gp_Pnt2d (BegO.X()+ (segO.X()*parOSP),
435 BegO.Y()+ (segO.Y()*parOSP)),
436 Intf_EDGE,iObje1,parOSP,
437 Intf_EDGE,iObje2,parTSP,sinTeta));
438 }
439
440 // Otherwise it is required to check if there is no other
441 else if (rayIntf>=Tolerance) {
442 Standard_Real deltaO=rayIntf/lgO;
443 Standard_Real deltaT=rayIntf/lgT;
444 Standard_Real x, y;
445 Standard_Real parOdeb=parOSP-deltaO;
446 Standard_Real parOfin=parOSP+deltaO;
447 Standard_Real parTdeb=parTSP-sigPS*deltaT;
448 Standard_Real parTfin=parTSP+sigPS*deltaT;
449 if (nbpi==0) {
450 parO[1]=parOdeb;
451 parO[2]=parOfin;
452 parT[1]=parTdeb;
453 parT[2]=parTfin;
454 while (nbpi<2) {
455 nbpi++;
456 x=BegO.X()+ (segO.X()*parO[nbpi]);
457 y=BegO.Y()+ (segO.Y()*parO[nbpi]);
458 thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y),
459 Intf_EXTERNAL, iObje1, parO[nbpi],
460 Intf_EXTERNAL, iObje2, parT[nbpi],
461 sinTeta));
462 }
463 }
464 else { //nbpi>0
465 if (nbpi==1) {
466 Standard_Boolean ok=Standard_True;
467 if (0.<parOdeb && parOdeb<1. && 0.<parTdeb && parTdeb<1. ) {
468 parO[nbpi+1]=parOdeb;
469 parT[nbpi+1]=parTdeb;
470 }
471 else if (0.<parOfin && parOfin<1. && 0.<parTfin && parTfin<1. ) {
472 parO[nbpi+1]= parOfin;
473 parT[nbpi+1]= parTfin;
474 }
475 else {
476 ok=Standard_False;
477 }
478
479 if (ok) {
480 x=BegO.X()+ (segO.X()*parO[nbpi+1]);
481 y=BegO.Y()+ (segO.Y()*parO[nbpi+1]);
482 if (thePi(1).Pnt().Distance(gp_Pnt(x, y, 0)) >= (Tolerance/4.)) {
483 nbpi++;
484 thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y),
485 Intf_EXTERNAL, iObje1, parO[nbpi],
486 Intf_EXTERNAL, iObje2, parT[nbpi],
487 sinTeta));
488 }
489 }
490 }
491 else { // plus d une singularite
492 Standard_Real parOmin=parO[1];
493 Standard_Real parOmax=parO[1];
494 Standard_Real parTmin=parT[1];
495 Standard_Real parTmax=parT[1];
496 for (Standard_Integer i=2; i<=nbpi; i++) {
497 parOmin=Min(parOmin, parO[i]);
498 parOmax=Max(parOmax, parO[i]);
499 parTmin=Min(parTmin, parT[i]);
500 parTmax=Max(parTmax, parT[i]);
501 }
502
503 Standard_Real delta;
504 if (parOdeb<0.) {
505 delta=-parOdeb;
506 parOdeb=0.;
507 parTdeb=parTdeb+sigPS*(delta*(deltaT/deltaO));
508 }
509 if (parOfin>1.) {
510 delta=parOfin-1.;
511 parOfin=1.;
512 parTfin=parTfin-sigPS*(delta*(deltaT/deltaO));
513 }
514 if (sigPS>0.) {
515 if (parTdeb<0.) {
516 delta=-parTdeb;
517 parTdeb=0.;
518 parOdeb=parOdeb+delta*(deltaO/deltaT);
519 }
520 if (parTfin>1.) {
521 delta=parTfin-1.;
522 parTfin=1.;
523 parOfin=parOfin-delta*(deltaO/deltaT);
524 }
525 }
526 else {
527 if (parTdeb>1.) {
528 delta=parTdeb-1.;
529 parTdeb=1.;
530 parOdeb=parOdeb+delta*(deltaO/deltaT);
531 }
532 if (parTfin<0.) {
533 delta=-parTfin;
534 parTfin=0.;
535 parOfin=parOfin-delta*(deltaO/deltaT);
536 }
537 }
538
539 if ((parOdeb<parOmin && parOmin>0.) ||
540 (sigPS>0. && parTdeb<parTmin && parTmin>0.) ||
541 (sigPS<0. && parTdeb>parTmax && parTmax<1.)) {
542 nbpi++;
543 parO[nbpi]=Max(0., Min(1., parOdeb));
544 parT[nbpi]=Max(0., Min(1., parTdeb));
545 x=BegO.X()+ (segO.X()*parO[nbpi]);
546 y=BegO.Y()+ (segO.Y()*parO[nbpi]);
547 thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y),
548 Intf_EXTERNAL, iObje1, parO[nbpi],
549 Intf_EXTERNAL, iObje2, parT[nbpi],
550 sinTeta));
551 }
552
553 if ((parOfin>parOmax && parOmax<1.) ||
554 (sigPS<0. && parTfin<parTmin && parTmin>0.) ||
555 (sigPS>0. && parTfin>parTmax && parTmax<1.)) {
556 nbpi++;
557 parO[nbpi]=Min(1., Max(0., parOfin));
558 parT[nbpi]=Min(1., Max(0., parTfin));
559 x=BegO.X()+ (segO.X()*parO[nbpi]);
560 y=BegO.Y()+ (segO.Y()*parO[nbpi]);
561 thePi.Append(Intf_SectionPoint(gp_Pnt2d(x, y),
562 Intf_EXTERNAL, iObje1, parO[nbpi],
563 Intf_EXTERNAL, iObje2, parT[nbpi],
564 sinTeta));
565 }
566 }
567 }
568 }
569 }
570
571 //-- lbr : The points too close to each other are suspended
572 Standard_Boolean suppr;
573 do {
574 suppr=Standard_False;
575 for(Standard_Integer i=2; suppr==Standard_False && i<=nbpi; i++) {
576 const gp_Pnt& Pim1 = thePi(i-1).Pnt();
577 const gp_Pnt& Pi = thePi(i).Pnt();
578 Standard_Real d=Pi.Distance(Pim1);
579 d*=50.0;
580 if(d<lgT && d<lgO) {
581 for(Standard_Integer j=i; j<nbpi; j++) {
582 thePi(j)=thePi(j+1);
583 }
584 nbpi--;
585 suppr=Standard_True;
586 }
587 }
588 }
589 while(suppr==Standard_True);
590
591
592
593
594
595
596 if (nbpi==1) {
597 if (edgeSP) {
598 thePi(1)=Intf_SectionPoint(gp_Pnt2d (BegO.X()+ (segO.X()*parOSP),
599 BegO.Y()+ (segO.Y()*parOSP)),
600 Intf_EDGE,iObje1,parOSP,
601 Intf_EDGE,iObje2,parTSP,sinTeta);
602 parO[1]=parOSP;
603 parT[1]=parTSP;
604 }
605 if (!SelfIntf) {
606 Standard_Boolean contains = Standard_False;
607 for (Standard_Integer i = 1; i <= mySPoins.Length(); i++)
608 if (thePi(1).IsEqual(mySPoins(i))) {
609 contains = Standard_True;
610 break;
611 }
612 if (!contains)
613 mySPoins.Append(thePi(1));
614 }
615 else if (iObje2-iObje1!=1 &&
616 (!oClos || (iObje1!=1 && iObje2!=nbso))) {
617 mySPoins.Append(thePi(1));
618 }
619 }
620
621 else if (nbpi>=2) {
622 Intf_TangentZone TheTZ;
623 if (nbpi==2) {
624 TheTZ.PolygonInsert(thePi(1));
625 TheTZ.PolygonInsert(thePi(2));
626 }
627 else {
628 Standard_Integer lpj;
629 Standard_Integer lmin=1;
630 Standard_Integer lmax=1;
631 for (lpj=2; lpj<=nbpi; lpj++) {
632 if (parO[lpj]<parO[lmin]) lmin=lpj;
633 else if (parO[lpj]>parO[lmax]) lmax=lpj;
634 }
635 TheTZ.PolygonInsert(thePi(lmin));
636 TheTZ.PolygonInsert(thePi(lmax));
637
638 Standard_Integer ltmin=1;
639 Standard_Integer ltmax=1;
640 for (lpj=2; lpj<=nbpi; lpj++) {
641 if (parT[lpj]<parT[ltmin]) ltmin=lpj;
642 else if (parT[lpj]>parT[ltmax]) ltmax=lpj;
643 }
644 if (ltmin!=lmin && ltmin!=lmax) TheTZ.PolygonInsert(thePi(ltmin));
645 if (ltmax!=lmin && ltmax!=lmax) TheTZ.PolygonInsert(thePi(ltmax));
646 }
647
648 if (edgeSP) TheTZ.PolygonInsert(Intf_SectionPoint
649 (gp_Pnt2d (BegO.X()+ (segO.X()*parOSP),
650 BegO.Y()+ (segO.Y()*parOSP)),
651 Intf_EDGE,iObje1,parOSP,
652 Intf_EDGE,iObje2,parTSP,sinTeta));
653
654 Standard_Integer nbtz=myTZones.Length();
655 #if 0
656 Standard_Integer decaltz=0;
657 for (Standard_Integer ltz=1; ltz<=nbtz; ltz++) {
658 if (TheTZ.HasCommonRange(myTZones(ltz-decaltz))) {
659 TheTZ.Append(myTZones(ltz-decaltz));
660 myTZones.Remove(ltz-decaltz);
661 decaltz++;
662 }
663 }
664 myTZones.Append(TheTZ);
665 #else
666 TColStd_ListOfInteger LIndex;
667 for (Standard_Integer ltz=1; ltz<=nbtz; ltz++) {
668 if (TheTZ.HasCommonRange(myTZones(ltz))) {
669 LIndex.Append(ltz);
670 }
671 }
672 //------------------------------------------------------------------------
673 //-- The list is parsed in ascending order by index, zone and tg
674 //--
675 if(LIndex.IsEmpty()) {
676 myTZones.Append(TheTZ);
677 }
678 else {
679 Standard_Integer indexfirst = LIndex.First();
680 LIndex.RemoveFirst();
681 Standard_Integer decal = 0;
682 myTZones(indexfirst).Append(TheTZ);
683 while(!LIndex.IsEmpty()) {
684 Standard_Integer index = LIndex.First();
685 LIndex.RemoveFirst();
686 myTZones(indexfirst).Append(myTZones(index-decal));
687 myTZones.Remove(index-decal);
688 decal++;
689 }
690 }
691 #endif
692 }
693 }
694