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