e553c45eae064758890fc6597f74487d6e3e8939
[occt.git] / src / Intf / Intf_InterferencePolygon2d.cxx
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
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
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
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
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
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
142 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
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
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
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
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 }