0024510: Remove unused local variables
[occt.git] / src / IntCurve / IntCurve_IntPolyPolyGen.gxx
1 // Created on: 1992-10-13
2 // Created by: Laurent BUCHARD
3 // Copyright (c) 1992-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 //  Modified by skv - Tue Mar  1 14:22:09 2005 OCC8169
18
19
20 #ifndef DEB
21 #define No_Standard_RangeError
22 #define No_Standard_OutOfRange
23 #endif
24
25
26 #include <Standard_ConstructionError.hxx>
27
28 #include <IntRes2d_Domain.hxx>
29 #include <IntRes2d_Position.hxx>
30 #include <IntRes2d_Transition.hxx>
31 #include <IntRes2d_IntersectionPoint.hxx>
32 #include <IntRes2d_IntersectionSegment.hxx>
33
34
35 #include <IntImpParGen.hxx>
36
37 #include <Intf_SectionPoint.hxx>
38 #include <Intf_SectionLine.hxx>
39 #include <Intf_TangentZone.hxx>
40 #include <Intf_InterferencePolygon2d.hxx>
41
42 #include <gp_Vec2d.hxx>
43
44 #include <math_Vector.hxx>
45 #include <math_FunctionSetRoot.hxx>
46 #include <math_NewtonFunctionSetRoot.hxx>
47 #include <NCollection_Handle.hxx>
48
49 //======================================================================
50
51 //  Modified by skv - Tue Mar  1 14:22:09 2005 OCC8169 Begin
52 // #define NBITER_MAX_POLYGON 3
53 #define NBITER_MAX_POLYGON 10
54 //  Modified by skv - Tue Mar  1 14:22:09 2005 OCC8169 End
55 #define TOL_CONF_MINI   0.0000000001
56 #define TOL_MINI        0.0000000001
57
58 //----------------------------------------------------------------------
59
60
61
62
63
64 Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1
65                                 ,const TheCurve& C1
66                                 ,const Standard_Real u
67                                 ,const IntRes2d_Domain& D2
68                                 ,const TheCurve& C2
69                                 ,const Standard_Real v
70                                 ,const Standard_Real TolConf
71                                 ,IntRes2d_IntersectionPoint& IntPt
72                                 ,Standard_Boolean& HeadOn1
73                                 ,Standard_Boolean& HeadOn2
74                                 ,Standard_Boolean& EndOn1
75                                 ,Standard_Boolean& EndOn2
76                                 ,Standard_Integer  PosSegment);
77
78
79 //======================================================================
80 IntCurve_IntPolyPolyGen::IntCurve_IntPolyPolyGen(void) {
81   done = Standard_False;
82 }
83 //======================================================================
84 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
85                                       ,const IntRes2d_Domain& D1
86                                       ,const TheCurve& C2
87                                       ,const IntRes2d_Domain& D2
88                                       ,const Standard_Real TheTolConf
89                                       ,const Standard_Real TheTol)
90 {
91   this->ResetFields();
92   DomainOnCurve1=D1;
93   DomainOnCurve2=D2; 
94   Standard_Real DU = D1.LastParameter()-D1.FirstParameter();
95   Standard_Real DV = D2.LastParameter()-D2.FirstParameter();
96   Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol;
97   Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf;
98   Perform(C1,D1,C2,D2,TlConf,Tl,0,DU,DV);
99   //----------------------------------------------------------------------
100   //-- Traitement des points en bouts 
101   //----------------------------------------------------------------------
102   Standard_Boolean HeadOn1 = Standard_False;
103   Standard_Boolean HeadOn2 = Standard_False;
104   Standard_Boolean EndOn1  = Standard_False;
105   Standard_Boolean EndOn2  = Standard_False;
106   Standard_Integer i;
107   Standard_Integer n=this->NbPoints();
108
109
110   //--------------------------------------------------------------------
111   //-- On ne rejette les points Head Head ... End End 
112   //-- si ils figurent deja dans un bout de segment 
113   //-- ( On ne peut pas tester les egalites sur les parametres)
114   //-- ( ces points n etant pas trouves a EpsX pres           )
115   //-- PosSegment =            1    si Head Head
116   //--                       2      si Head End
117   //--                     4        si End  Head
118   //--                   8          si End  End
119   //--------------------------------------------------------------------
120   Standard_Integer PosSegment = 0;
121
122   for(i=1;i<=n;i++) { 
123     IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
124     if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True;
125     else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True;
126
127     IntRes2d_Position Pos2 =  this->Point(i).TransitionOfSecond().PositionOnCurve();
128     if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True;
129     else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True;
130
131     if(Pos1 == IntRes2d_Head) { 
132       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
133       else if(Pos2 == IntRes2d_End) PosSegment|=2;
134     }
135     else if(Pos1 == IntRes2d_End) { 
136       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
137       else if(Pos2 == IntRes2d_End) PosSegment|=8;
138     }
139   }
140   
141   n=this->NbSegments();
142   for(i=1;i<=n;i++) { 
143     IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
144     if(Pos1 == IntRes2d_Head)     HeadOn1 = Standard_True;
145     else if(Pos1 == IntRes2d_End) EndOn1  = Standard_True;
146     
147     IntRes2d_Position Pos2 =  this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
148     if(Pos2 == IntRes2d_Head)      HeadOn2 = Standard_True;
149     else if(Pos2 == IntRes2d_End)  EndOn2  = Standard_True;
150
151     if(Pos1 == IntRes2d_Head) { 
152       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
153       else if(Pos2 == IntRes2d_End) PosSegment|=2;
154     }
155     else if(Pos1 == IntRes2d_End) { 
156       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
157       else if(Pos2 == IntRes2d_End) PosSegment|=8;
158     }
159
160     Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
161     if(Pos1 == IntRes2d_Head)     HeadOn1 = Standard_True;
162     else if(Pos1 == IntRes2d_End) EndOn1  = Standard_True;
163     
164     Pos2 =  this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
165     if(Pos2 == IntRes2d_Head)     HeadOn2 = Standard_True;
166     else if(Pos2 == IntRes2d_End) EndOn2  = Standard_True;
167
168     if(Pos1 == IntRes2d_Head) { 
169       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
170       else if(Pos2 == IntRes2d_End) PosSegment|=2;
171     }
172     else if(Pos1 == IntRes2d_End) { 
173       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
174       else if(Pos2 == IntRes2d_End) PosSegment|=8;
175     }
176   }
177
178   Standard_Real U0 = D1.FirstParameter();
179   Standard_Real U1 = D1.LastParameter();
180   Standard_Real V0 = D2.FirstParameter();
181   Standard_Real V1 = D2.LastParameter();
182   IntRes2d_IntersectionPoint IntPt;
183   
184   if(D1.FirstTolerance() || D2.FirstTolerance()) { 
185     if(HeadOrEndPoint(D1,C1,U0,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) 
186       this->Insert(IntPt);
187   }
188   if(D1.FirstTolerance() || D2.LastTolerance()) { 
189     if(HeadOrEndPoint(D1,C1,U0,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) 
190       this->Insert(IntPt);
191   }
192   if(D1.LastTolerance() || D2.FirstTolerance()) {
193     if(HeadOrEndPoint(D1,C1,U1,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) 
194       this->Insert(IntPt);
195   }
196   if(D1.LastTolerance() ||  D2.LastTolerance()) { 
197     if(HeadOrEndPoint(D1,C1,U1,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) 
198       this->Insert(IntPt);
199   }
200 }
201
202
203 //======================================================================
204 //==      A u t o   I n t e r s e c t i o  n 
205 //======================================================================
206 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
207                                       ,const IntRes2d_Domain& D1
208                                       ,const Standard_Real TheTolConf
209                                       ,const Standard_Real TheTol)
210 {
211
212   this->ResetFields();
213   DomainOnCurve1=D1;
214   DomainOnCurve2=D1; 
215   Standard_Real DU = D1.LastParameter()-D1.FirstParameter();
216   Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol;
217   Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf;
218   Perform(C1,D1,TlConf,Tl,0,DU,DU);
219   Standard_Integer i;
220   Standard_Integer n=this->NbPoints();
221
222   //--------------------------------------------------------------------
223   //-- On ne rejette les points Head Head ... End End 
224   //-- si ils figurent deja dans un bout de segment 
225   //-- ( On ne peut pas tester les egalites sur les parametres)
226   //-- ( ces points n etant pas trouves a EpsX pres           )
227   //-- PosSegment =            1    si Head Head
228   //--                       2      si Head End
229   //--                     4        si End  Head
230   //--                   8          si End  End
231   //--------------------------------------------------------------------
232   Standard_Integer PosSegment = 0;
233
234   for(i=1;i<=n;i++) { 
235     IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
236     IntRes2d_Position Pos2 =  this->Point(i).TransitionOfSecond().PositionOnCurve();
237
238     if(Pos1 == IntRes2d_Head) { 
239       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
240       else if(Pos2 == IntRes2d_End) PosSegment|=2;
241     }
242     else if(Pos1 == IntRes2d_End) { 
243       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
244       else if(Pos2 == IntRes2d_End) PosSegment|=8;
245     }
246   }
247   
248   n=this->NbSegments();
249   for(i=1;i<=n;i++) { 
250     IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
251     IntRes2d_Position Pos2 =  this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
252
253     if(Pos1 == IntRes2d_Head) { 
254       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
255       else if(Pos2 == IntRes2d_End) PosSegment|=2;
256     }
257     else if(Pos1 == IntRes2d_End) { 
258       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
259       else if(Pos2 == IntRes2d_End) PosSegment|=8;
260     }
261
262     Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
263     Pos2 =  this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
264
265     if(Pos1 == IntRes2d_Head) { 
266       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
267       else if(Pos2 == IntRes2d_End) PosSegment|=2;
268     }
269     else if(Pos1 == IntRes2d_End) { 
270       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
271       else if(Pos2 == IntRes2d_End) PosSegment|=8;
272     }
273   }
274 }
275 //======================================================================
276
277 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
278                                       ,const IntRes2d_Domain& D1
279                                       ,const Standard_Real TolConf
280                                       ,const Standard_Real Tol
281                                       ,const Standard_Integer NbIter
282                                       ,const Standard_Real /*DeltaU*/
283                                       ,const Standard_Real) {
284   
285   gp_Vec2d Tan1,Tan2,Norm1,Norm2;
286   gp_Pnt2d P1,P2;
287   Standard_Integer nbsamples;
288   done = Standard_False;
289   
290   nbsamples = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
291
292   if(NbIter>3 || (NbIter>2 && nbsamples>100)) return;
293
294   nbsamples*=2;   //---  On prend systematiquement 2 fois plus de points que 
295                   //--   sur une courbe normale.  
296                   //--   Les courbes auto-intersectantes donne souvent des 
297                   //--   polygones assez loin de la courbe a parametre ct.
298
299   if(NbIter>0) { 
300     nbsamples=(3*(nbsamples*NbIter))/2;
301   }
302   IntCurve_ThePolygon2d Poly1(C1,nbsamples,D1,Tol);
303   if(!Poly1.AutoIntersectionIsPossible()) { 
304     done = Standard_True;
305     return;
306   }
307   //-- Poly1.Dump();
308   //----------------------------------------------------------------------
309   //-- Si la deflection est inferieure a la Tolerance de Confusion
310   //-- Alors la deflection du polygone est fixee a TolConf
311   //-- (Detection des Zones de Tangence)
312   //----------------------------------------------------------------------
313   if(Poly1.DeflectionOverEstimation() < TolConf) { 
314     Poly1.SetDeflectionOverEstimation(TolConf);
315   }
316
317   Intf_InterferencePolygon2d InterPP(Poly1);  
318   IntCurve_ExactIntersectionPoint  EIP(C1,C1,TolConf);
319   Standard_Real U,V;
320   
321   //----------------------------------------------------------------------
322   //-- Traitement des SectionPoint 
323   //----------------------------------------------------------------------
324   Standard_Integer Nbsp = InterPP.NbSectionPoints();
325   if(Nbsp>=1) {
326     
327     //-- ---------------------------------------------------------------------
328     //-- tri  tri  tri  tri  tri  tri  tri  tri  tri  tri  tri  tri  tri  tri 
329     //-- 
330     Standard_Integer* TriIndex     = new Standard_Integer [Nbsp+1];
331     Standard_Integer* PtrSegIndex1 = new Standard_Integer [Nbsp+1];
332     Standard_Integer* PtrSegIndex2 = new Standard_Integer [Nbsp+1];
333     Standard_Boolean Triok;
334     Standard_Integer SegIndex1,SegIndex2,SegIndex_1,SegIndex_2;
335 //    Standard_Real    ParamOn1,ParamOn2,ParamOn_1,ParamOn_2;
336     Standard_Real    ParamOn1,ParamOn2;
337     Intf_PIType      Type; 
338     Standard_Integer i ;
339     for( i=1;i<=Nbsp;i++) { 
340       TriIndex[i]=i;
341       const Intf_SectionPoint& SPnt1 = InterPP.PntValue(i);
342       SPnt1.InfoFirst(Type,PtrSegIndex1[i],ParamOn1);
343       SPnt1.InfoSecond(Type,PtrSegIndex2[i],ParamOn2);
344     }
345  
346
347     do { 
348       Triok=Standard_True;
349
350       for(Standard_Integer tr=1;tr<Nbsp;tr++) { 
351               SegIndex1=PtrSegIndex1[TriIndex[tr]];
352               SegIndex_1=PtrSegIndex1[TriIndex[tr+1]];
353
354               SegIndex2=PtrSegIndex2[TriIndex[tr]];
355               SegIndex_2=PtrSegIndex2[TriIndex[tr+1]];
356
357               if(SegIndex1 > SegIndex_1) { 
358                 Standard_Integer q=TriIndex[tr]; 
359                 TriIndex[tr]=TriIndex[tr+1];
360                 TriIndex[tr+1]=q;
361                 Triok=Standard_False;
362               }
363               else if(SegIndex1 == SegIndex_1) { 
364                 if(SegIndex2 > SegIndex_2) { 
365                   Standard_Integer q=TriIndex[tr]; 
366                   TriIndex[tr]=TriIndex[tr+1];
367                   TriIndex[tr+1]=q;
368                   Triok=Standard_False;
369                 }
370               }
371       }
372     }
373     while(Triok==Standard_False);
374
375     //-- supression des doublons Si Si !
376     for(i=1; i<Nbsp;i++) { 
377       if(   (PtrSegIndex1[TriIndex[i]] == PtrSegIndex1[TriIndex[i+1]])
378                 && (PtrSegIndex2[TriIndex[i]] == PtrSegIndex2[TriIndex[i+1]])) { 
379               TriIndex[i]=-i;
380       }
381     }
382
383     Standard_Integer Nelarg=(Poly1.NbSegments()/20);
384     if(Nelarg<2) Nelarg=2;
385
386     for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
387       if(TriIndex[sp]>0) { 
388               const Intf_SectionPoint& SPnt = InterPP.PntValue(TriIndex[sp]);
389         
390               SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
391               SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
392         
393               if(Abs(SegIndex1-SegIndex2)>1) { 
394           
395                 EIP.Perform(Poly1,Poly1,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
396                 if(EIP.NbRoots()==0) {
397                   //-- On supprime tous les segments voisins 
398                   for(Standard_Integer k=sp+1;k<=Nbsp;k++) { 
399                     Standard_Integer kk=TriIndex[k];
400                     // --- avoid negative indicies as well as in outer done
401                     if( kk > 0 ) {
402                             if(   Abs(SegIndex1-PtrSegIndex1[kk])< Nelarg
403                                && Abs(SegIndex2-PtrSegIndex2[kk])< Nelarg) { 
404                               TriIndex[k]=-k;
405                             }
406               }
407                   }
408                 }         
409                 else if(EIP.NbRoots()>=1) { 
410                   //--------------------------------------------------------------------
411                   //-- On verifie que le point trouve est bien une racine
412                   //--------------------------------------------------------------------
413                   EIP.Roots(U,V);
414
415                   TheCurveTool::D1(C1,U,P1,Tan1);
416                   TheCurveTool::D1(C1,V,P2,Tan2);
417                   Standard_Real Dist = P1.Distance(P2);
418                   Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1);
419             
420                   if(Abs(U-V)<=EpsX1) { 
421                     //-----------------------------------------
422                     //-- Solution non valide 
423                     //-- Les maths ont du converger vers une 
424                     //-- solution triviale ( point U = V )
425                     //-----------------------------------------
426                     Dist = TolConf+1.0;
427                   }
428             
429                   //-----------------------------------------------------------------
430                   //-- On verifie que le point (u,v) n existe pas deja 
431                   //--
432                   done = Standard_True;
433                   Standard_Integer nbp=NbPoints();
434             
435                   for(Standard_Integer p=1; p<=nbp; p++) { 
436                     const IntRes2d_IntersectionPoint& P=Point(p);
437                     if(Abs(U-P.ParamOnFirst()) <= EpsX1) { 
438                             if(Abs(V-P.ParamOnSecond()) <= EpsX1) { 
439                               Dist = TolConf+1.0;  p+=nbp;
440                             }
441                     }
442                   }
443             
444                   if(Dist <= TolConf) {    //-- Ou le point est deja present
445                     IntRes2d_Position Pos1 = IntRes2d_Middle;
446                     IntRes2d_Position Pos2 = IntRes2d_Middle;
447                     IntRes2d_Transition  Trans1,Trans2;
448                     //-----------------------------------------------------------------
449                     //-- Calcul des Positions des Points sur la courbe
450                     //--
451                     if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    
452                             Pos1 = IntRes2d_Head;
453                     else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) 
454                             Pos1 = IntRes2d_End;
455               
456                     if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    
457                             Pos2 = IntRes2d_Head;
458                     else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) 
459                             Pos2 = IntRes2d_End;
460                     //-----------------------------------------------------------------
461                     if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1
462                                                          ,Pos2,Tan2,Trans2
463                                                          ,TolConf) == Standard_False) 
464               {
465                             TheCurveTool::D2(C1,U,P1,Tan1,Norm1);
466                             TheCurveTool::D2(C1,V,P2,Tan2,Norm2);
467                             IntImpParGen::DetermineTransition( Pos1,Tan1,Norm1,Trans1
468                                                               ,Pos2,Tan2,Norm2,Trans2
469                                                               ,TolConf);
470                     }
471                     IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
472                     Insert(IP);
473                   }
474                 }
475               }
476       }
477     }
478     delete [] TriIndex;
479     delete [] PtrSegIndex1;
480     delete [] PtrSegIndex2;
481   }
482  done = Standard_True;
483 }
484
485
486 Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1
487                                 ,const TheCurve& C1
488                                 ,const Standard_Real tu
489                                 ,const IntRes2d_Domain& D2
490                                 ,const TheCurve& C2
491                                 ,const Standard_Real tv
492                                 ,const Standard_Real TolConf
493                                 ,IntRes2d_IntersectionPoint& IntPt
494                                 ,Standard_Boolean& HeadOn1
495                                 ,Standard_Boolean& HeadOn2
496                                 ,Standard_Boolean& EndOn1
497                                 ,Standard_Boolean& EndOn2
498                                 ,Standard_Integer PosSegment) { 
499
500   gp_Pnt2d P1,P2,SP1,SP2;
501   gp_Vec2d T1,T2,N1,N2;
502   Standard_Real u=tu;
503   Standard_Real v=tv;
504   Standard_Real svu = u;
505   Standard_Real svv = v;
506
507   TheCurveTool::D1(C1,u,P1,T1);
508   TheCurveTool::D1(C2,v,P2,T2);
509   
510   IntRes2d_Position Pos1 = IntRes2d_Middle; 
511   IntRes2d_Position Pos2 = IntRes2d_Middle;
512   IntRes2d_Transition Trans1,Trans2;
513
514   //----------------------------------------------------------------------
515   //-- Head On 1   :        Head1 <-> P2
516   if(P2.Distance(D1.FirstPoint())<=D1.FirstTolerance())    { 
517     Pos1 = IntRes2d_Head; 
518     HeadOn1 = Standard_True; 
519     SP1 = D1.FirstPoint();
520     u = D1.FirstParameter();
521   }
522   //----------------------------------------------------------------------
523   //-- End On 1   :         End1 <-> P2
524   else if(P2.Distance(D1.LastPoint())<=D1.LastTolerance()) { 
525     Pos1 = IntRes2d_End; 
526     EndOn1 = Standard_True;
527     SP1 = D1.LastPoint();
528     u = D1.LastParameter();
529   }
530
531   //----------------------------------------------------------------------
532   //-- Head On 2   :        Head2 <-> P1
533   else if(P1.Distance(D2.FirstPoint())<=D2.FirstTolerance())    { 
534     Pos2 = IntRes2d_Head; 
535     HeadOn2 = Standard_True; 
536     SP2 = D2.FirstPoint();
537     v = D2.FirstParameter();
538   }
539   //----------------------------------------------------------------------
540   //-- End On 2   :        End2 <-> P1
541   else if(P1.Distance(D2.LastPoint())<=D2.LastTolerance()) { 
542     Pos2 = IntRes2d_End; 
543     EndOn2 = Standard_True;
544     SP2 = D2.LastPoint();
545     v = D2.LastParameter();
546   }
547
548   Standard_Real EpsX1 = TheCurveTool::EpsX(C1);
549   Standard_Real EpsX2 = TheCurveTool::EpsX(C2);
550
551   if((Pos1 != IntRes2d_Middle)||(Pos2 !=  IntRes2d_Middle)) { 
552     if(Pos1 == IntRes2d_Middle) {
553       if(Abs(u-D1.FirstParameter()) <= EpsX1) { 
554               Pos1 = IntRes2d_Head;
555               P1 = D1.FirstPoint();
556               HeadOn1 = Standard_True;
557       }
558       else if(Abs(u-D1.LastParameter()) <= EpsX1) { 
559               Pos1 = IntRes2d_End;
560               P1 = D1.LastPoint();
561               EndOn1 = Standard_True;
562       }
563     }
564     else if(u!=tu) {
565       P1 = SP1; 
566     }
567       
568     
569     if(Pos2 == IntRes2d_Middle) { 
570       if(Abs(v-D2.FirstParameter()) <= EpsX2) { 
571               Pos2 = IntRes2d_Head;
572               HeadOn2 = Standard_True;
573               P2 = D2.FirstPoint();     
574               if(Pos1 != IntRes2d_Middle) {
575                 P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y()));
576               }
577               else { 
578                 P2 = P1; 
579               }
580       }
581       else if(Abs(v-D2.LastParameter()) <= EpsX2) { 
582               Pos2 = IntRes2d_End;
583               EndOn2 = Standard_True;
584               P2 = D2.LastPoint();
585               if(Pos1 != IntRes2d_Middle) {
586                 P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y()));
587               }
588               else { 
589                 P2 = P1; 
590               }
591       }
592     }
593
594     //--------------------------------------------------------------------
595     //-- On Teste si un point de bout de segment a deja ces trnasitions 
596     //-- Si Oui, on ne cree pas de nouveau point
597     //-- 
598     //-- PosSegment =            1    si Head Head
599     //--                       2      si Head End
600     //--                     4        si End  Head
601     //--                   8          si End  End
602     //--------------------------------------------------------------------
603     if(Pos1 == IntRes2d_Head) { 
604       if((Pos2 == IntRes2d_Head)&&(PosSegment & 1)) return(Standard_False);
605       if((Pos2 == IntRes2d_End )&&(PosSegment & 2)) return(Standard_False);
606     }
607     else if(Pos1 == IntRes2d_End) { 
608       if((Pos2 == IntRes2d_Head)&&(PosSegment & 4)) return(Standard_False);
609       if((Pos2 == IntRes2d_End )&&(PosSegment & 8)) return(Standard_False);
610     }
611
612
613     if(IntImpParGen::DetermineTransition( Pos1,T1,Trans1,Pos2,T2,Trans2,TolConf)
614        == Standard_False) { 
615       TheCurveTool::D2(C1,svu,P1,T1,N1);
616       TheCurveTool::D2(C2,svv,P2,T2,N2);
617       IntImpParGen::DetermineTransition(Pos1,T1,N1,Trans1,
618                                         Pos2,T2,N2,Trans2,TolConf);
619     }
620     IntPt.SetValues(P1,u,v,Trans1,Trans2,Standard_False);
621     return(Standard_True);
622   }
623   else 
624     return(Standard_False);
625 }
626
627
628 //======================================================================
629 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
630                                       ,const IntRes2d_Domain& D1
631                                       ,const TheCurve& C2
632                                       ,const IntRes2d_Domain& D2
633                                       ,const Standard_Real TolConf
634                                       ,const Standard_Real Tol
635                                       ,const Standard_Integer NbIter
636                                       ,const Standard_Real DeltaU
637                                       ,const Standard_Real DeltaV) {
638
639   Standard_Integer nbsamplesOnC1,nbsamplesOnC2;
640   done = Standard_False;
641
642   if(NbIter>NBITER_MAX_POLYGON) return;
643
644   nbsamplesOnC1 = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());      
645
646   if (NbIter == 0) // first time
647   {
648     if (nbsamplesOnC1 < 20)
649       nbsamplesOnC1 = 20;
650   }
651   else // NbIter > 0
652   {
653     nbsamplesOnC1=(5*(nbsamplesOnC1*NbIter))/4;
654   }
655   /////////////////////////////////////////////
656
657   nbsamplesOnC2 = TheCurveTool::NbSamples(C2,D2.FirstParameter(),D2.LastParameter());
658   
659   if (NbIter == 0) // first time
660   {
661     if (nbsamplesOnC2 < 20)
662       nbsamplesOnC2 = 20;
663   }
664   else // NbIter > 0
665   {
666     nbsamplesOnC2=(5*(nbsamplesOnC2*NbIter))/4;
667   }
668   /////////////////////////////////////////////
669
670   
671   NCollection_Handle<IntCurve_ThePolygon2d> aPoly1 ,aPoly2;
672   if(nbsamplesOnC2 > nbsamplesOnC1) { 
673     aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);  
674     if(aPoly1->DeflectionOverEstimation() < TolConf) { 
675       aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
676     }
677     else { 
678       aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol,aPoly1->Bounding());
679       aPoly1->SetDeflectionOverEstimation( aPoly2->DeflectionOverEstimation()
680                                             + aPoly1->DeflectionOverEstimation());
681       aPoly1->ComputeWithBox(C1,aPoly2->Bounding());
682     }
683   }
684   else { 
685     aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);  
686     if(aPoly2->DeflectionOverEstimation() < TolConf) {
687       aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
688     }
689     else { 
690       aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol,aPoly2->Bounding());
691       aPoly2->SetDeflectionOverEstimation( aPoly2->DeflectionOverEstimation()
692                                             + aPoly1->DeflectionOverEstimation());
693       aPoly2->ComputeWithBox(C2,aPoly1->Bounding());
694     }
695   }
696   //----------------------------------------------------------------------
697   //-- Si la deflection est inferieure a la Tolerance de Confusion
698   //-- Alors la deflection du polygone est fixee a TolConf
699   //-- (Detection des Zones de Tangence)
700   //----------------------------------------------------------------------
701
702   if(aPoly1->DeflectionOverEstimation() < TolConf) { 
703     aPoly1->SetDeflectionOverEstimation(TolConf);
704   }
705   if(aPoly2->DeflectionOverEstimation() < TolConf) { 
706     aPoly2->SetDeflectionOverEstimation(TolConf);
707   }
708   //for case when a few polygon points were replaced by line
709   //if exact solution was not found 
710   //then search of precise solution will be repeat 
711   //for polygon conatins all initial points
712   //secondary search will be performed only for case when initial points
713   //were dropped
714   Standard_Boolean isFullRepresentation = ( aPoly1->NbSegments() == nbsamplesOnC1 && 
715             aPoly2->NbSegments() == nbsamplesOnC2 );
716   
717   if( !findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
718           DeltaU, DeltaV, *aPoly1, *aPoly2, isFullRepresentation ) && !isFullRepresentation ) 
719   {
720     if(aPoly1->NbSegments() < nbsamplesOnC1)
721     {
722       aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
723     }
724     if(aPoly2->NbSegments() < nbsamplesOnC2)
725     {
726       aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
727     }
728
729     findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
730       DeltaU, DeltaV, *aPoly1, *aPoly2, 
731       Standard_True);   
732
733   }
734  
735   done = Standard_True;
736 }
737
738 //======================================================================
739 // Purpose : findIntersect
740 //======================================================================
741
742 Standard_Boolean IntCurve_IntPolyPolyGen::findIntersect( 
743     const TheCurve& C1,
744           const IntRes2d_Domain& D1,
745           const TheCurve& C2,
746           const IntRes2d_Domain& D2,
747           const Standard_Real TolConf,
748           const Standard_Real Tol,
749           const Standard_Integer NbIter,
750           const Standard_Real DeltaU,
751           const Standard_Real DeltaV,
752           const IntCurve_ThePolygon2d& thePoly1,
753           const IntCurve_ThePolygon2d& thePoly2,
754           Standard_Boolean isFullPolygon )
755 {
756
757   gp_Vec2d Tan1,Tan2,Norm1,Norm2;
758   gp_Pnt2d P1,P2;
759   Intf_InterferencePolygon2d InterPP(thePoly1,thePoly2);  
760   IntCurve_ExactIntersectionPoint  EIP(C1,C2,TolConf);
761   Standard_Real U = 0., V = 0.;
762   Standard_Boolean AnErrorOccurred = Standard_False;
763   done = Standard_True; // To prevent exception in nbp=NbPoints();
764   //----------------------------------------------------------------------
765   //-- Traitement des SectionPoint 
766   //----------------------------------------------------------------------
767   Standard_Integer Nbsp = InterPP.NbSectionPoints();
768   for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
769     const Intf_SectionPoint& SPnt = InterPP.PntValue(sp);
770     Standard_Integer SegIndex1,SegIndex2;
771     Standard_Real    ParamOn1,ParamOn2;
772     Intf_PIType      Type;
773
774     SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
775     SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
776     EIP.Perform(thePoly1,thePoly2,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
777     AnErrorOccurred = EIP.AnErrorOccurred();
778
779     if( !EIP.NbRoots() && !isFullPolygon)
780       return Standard_False;
781
782     if(AnErrorOccurred) 
783     {
784       continue;
785     }
786
787     //--------------------------------------------------------------------
788     //-- On verifie que le point trouve est bien une racine
789     //--------------------------------------------------------------------
790     EIP.Roots(U,V);
791     TheCurveTool::D1(C1,U,P1,Tan1);
792     TheCurveTool::D1(C2,V,P2,Tan2);
793     Standard_Real Dist = P1.Distance(P2);
794     //-----------------------------------------------------------------
795     //-- On verifie que le point (u,v) n existe pas deja 
796     //--
797     Standard_Integer nbp=NbPoints();
798     Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1);
799     Standard_Real EpsX2 = 10.0*TheCurveTool::EpsX(C2);
800     for(Standard_Integer p=1; p<=nbp; p++) { 
801       const IntRes2d_IntersectionPoint& P=Point(p);
802       if(Abs(U-P.ParamOnFirst()) <= EpsX1) { 
803         if(Abs(V-P.ParamOnSecond()) <= EpsX2) { 
804           Dist = TolConf+1.0;  p+=nbp;
805         }
806       }
807     }
808
809     if(Dist <= TolConf) {    //-- Ou le point est deja present
810       IntRes2d_Position Pos1 = IntRes2d_Middle;
811       IntRes2d_Position Pos2 = IntRes2d_Middle;
812       IntRes2d_Transition  Trans1,Trans2;
813       //-----------------------------------------------------------------
814       //-- Calcul des Positions des Points sur la courbe
815       //--
816       if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    
817         Pos1 = IntRes2d_Head;
818       else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) 
819         Pos1 = IntRes2d_End;
820
821       if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    
822         Pos2 = IntRes2d_Head;
823       else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) 
824         Pos2 = IntRes2d_End;
825       //-----------------------------------------------------------------
826       //-- Calcul des Transitions (Voir IntImpParGen.cxx)
827       //--
828       if(IntImpParGen::DetermineTransition (Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf) == Standard_False) { 
829         TheCurveTool::D2(C1,U,P1,Tan1,Norm1);
830         TheCurveTool::D2(C2,V,P2,Tan2,Norm2);
831         IntImpParGen::DetermineTransition (Pos1, Tan1, Norm1, Trans1, Pos2, Tan2, Norm2, Trans2, TolConf);
832       }
833       IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
834       Insert(IP);
835     }
836   }
837   
838   //----------------------------------------------------------------------
839   //-- Traitement des TangentZone
840   //----------------------------------------------------------------------
841   Standard_Integer Nbtz = InterPP.NbTangentZones();
842   for(Standard_Integer tz=1; tz <= Nbtz; tz++) {
843     Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
844     //====================================================================
845     //== Recherche du premier et du dernier point dans la zone de tg.
846     //====================================================================
847     Standard_Real ParamSupOnCurve2,ParamInfOnCurve2;
848     Standard_Real ParamSupOnCurve1,ParamInfOnCurve1;
849 //    Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2;
850     Standard_Integer SegIndex1onP1,SegIndex1onP2;
851     Intf_PIType Type;
852     Standard_Real ParamOnLine;
853     Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup;
854     ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast();
855     ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast();
856     for(Standard_Integer qq=1;qq<=NbPnts;qq++) { 
857       const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
858       //====================================================================
859       //== On discretise sur les zones de tangence 
860       //== Test d arret : 
861       //==      Compteur 
862       //==     Deflection  < Tolerance 
863       //==  OU Echantillon < EpsX   (normalement la premiere condition est 
864       //==                           plus severe)
865       //====================================================================
866 //      Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup;
867       Standard_Real _PolyUInf,_PolyVInf;
868
869       SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine);
870       if(SegIndex1onP1 > thePoly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; }
871       if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; }
872       _PolyUInf = thePoly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine);
873       
874       SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine);
875       if(SegIndex1onP2 > thePoly2.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; }
876       if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; }
877       _PolyVInf = thePoly2.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine);
878       
879       //----------------------------------------------------------------------
880
881       if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf;
882       if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf;
883
884       if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf;
885       if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf;
886     }
887
888     PolyUInf= ParamInfOnCurve1;
889     PolyUSup= ParamSupOnCurve1;
890     PolyVInf= ParamInfOnCurve2;
891     PolyVSup= ParamSupOnCurve2;
892     
893     TheCurveTool::D0(C1,PolyUInf,P1);
894     TheCurveTool::D0(C2,PolyVInf,P2);
895     Standard_Real distmemesens = P1.SquareDistance(P2);
896     TheCurveTool::D0(C2,PolyVSup,P2);
897     Standard_Real distdiffsens = P1.SquareDistance(P2);
898     if(distmemesens > distdiffsens) { 
899       Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty;
900     }
901
902     if(  (  (thePoly1.DeflectionOverEstimation() > TolConf)
903             ||(thePoly2.DeflectionOverEstimation() > TolConf))
904             &&(NbIter<NBITER_MAX_POLYGON)) {
905       
906       IntRes2d_Domain RecursD1( TheCurveTool::Value(C1,ParamInfOnCurve1)
907                                ,ParamInfOnCurve1,TolConf
908                                ,TheCurveTool::Value(C1,ParamSupOnCurve1)
909                                ,ParamSupOnCurve1,TolConf);
910       IntRes2d_Domain RecursD2( TheCurveTool::Value(C2,ParamInfOnCurve2)
911                                ,ParamInfOnCurve2,TolConf
912                                ,TheCurveTool::Value(C2,ParamSupOnCurve2)
913                                ,ParamSupOnCurve2,TolConf);
914       //-- On ne delete pas thePoly1(2) ,
915       //-- ils sont detruits enfin de fct. 
916       //-- !! Pas de return intempestif !!
917       Perform(C1,RecursD1,C2,RecursD2,Tol,TolConf,NbIter+1,DeltaU,DeltaV);
918     }
919     else { 
920       //-----------------------------------------------------------------
921       //-- Calcul des Positions des Points sur la courbe et des 
922       //-- Transitions sur chaque borne du segment
923       
924       IntRes2d_Position Pos1 = IntRes2d_Middle;
925       IntRes2d_Position Pos2 = IntRes2d_Middle;
926       IntRes2d_Transition  Trans1,Trans2;
927       
928       TheCurveTool::D1(C1,PolyUInf,P1,Tan1);
929       TheCurveTool::D1(C2,PolyVInf,P2,Tan2);
930       
931       if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    { 
932               Pos1 = IntRes2d_Head;
933       }
934       else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { 
935               Pos1 = IntRes2d_End;  
936       }
937       if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    { 
938               Pos2 = IntRes2d_Head; 
939       }
940       else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { 
941               Pos2 = IntRes2d_End;  
942       }
943
944       if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { 
945               PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
946       }
947       else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { 
948               PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
949       }
950       else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { 
951               PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
952       }
953       else { 
954               PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
955       }
956       
957
958
959       if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf) 
960                == Standard_False)
961       {
962               TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1);
963               TheCurveTool::D2(C2,PolyVInf,P2,Tan2,Norm2);
964               IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
965                                                 Pos2,Tan2,Norm2,Trans2,TolConf);
966       }
967       IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf
968                                         ,Trans1,Trans2,Standard_False);
969       //----------------------------------------------------------------------
970       
971       if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1)) 
972               || (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C2)))
973       { 
974               Insert(PtSeg1);
975       }
976       else 
977       { 
978               TheCurveTool::D1(C1,PolyUSup,P1,Tan1);
979               TheCurveTool::D1(C2,PolyVSup,P2,Tan2);
980               Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle;
981           
982               if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    { 
983                 Pos1 = IntRes2d_Head; 
984               }
985               else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { 
986                 Pos1 = IntRes2d_End;  
987               }
988               if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    { 
989                 Pos2 = IntRes2d_Head; 
990               }
991               else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { 
992                 Pos2 = IntRes2d_End;  
993               }
994
995
996               if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { 
997                 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
998               }
999               else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { 
1000                 PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1001               }
1002               else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { 
1003                 PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1004               }
1005               else { 
1006                 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1007               }
1008         
1009         if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
1010            ==Standard_False) { 
1011           TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1);
1012           TheCurveTool::D2(C2,PolyVSup,P2,Tan2,Norm2);
1013           IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
1014                                             Pos2,Tan2,Norm2,Trans2,TolConf);
1015         }
1016         IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup
1017                                           ,Trans1,Trans2,Standard_False);
1018         
1019               Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True;
1020               if(ParamInfOnCurve1 > ParamSupOnCurve1) {
1021                 IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False);
1022                 Append(Seg);
1023               }
1024               else { 
1025                 IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False);
1026                 Append(Seg);
1027               }
1028       }
1029     }
1030   }
1031  return Standard_True;
1032 }
1033