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