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