Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/opencascade/IntCurve_IntPolyPolyGen.gxx is written in an unsupported language. File is not indexed.

0001 // Created on: 1992-10-13
0002 // Created by: Laurent BUCHARD
0003 // Copyright (c) 1992-1999 Matra Datavision
0004 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0005 //
0006 // This file is part of Open CASCADE Technology software library.
0007 //
0008 // This library is free software; you can redistribute it and/or modify it under
0009 // the terms of the GNU Lesser General Public License version 2.1 as published
0010 // by the Free Software Foundation, with special exception defined in the file
0011 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0012 // distribution for complete text of the license and disclaimer of any warranty.
0013 //
0014 // Alternatively, this file may be used under the terms of Open CASCADE
0015 // commercial license or contractual agreement.
0016 
0017 //  Modified by skv - Tue Mar  1 14:22:09 2005 OCC8169
0018 
0019 
0020 #ifndef OCCT_DEBUG
0021 #define No_Standard_RangeError
0022 #define No_Standard_OutOfRange
0023 #endif
0024 
0025 
0026 #include <Standard_ConstructionError.hxx>
0027 
0028 #include <IntRes2d_Domain.hxx>
0029 #include <IntRes2d_Position.hxx>
0030 #include <IntRes2d_Transition.hxx>
0031 #include <IntRes2d_IntersectionPoint.hxx>
0032 #include <IntRes2d_IntersectionSegment.hxx>
0033 
0034 
0035 #include <IntImpParGen.hxx>
0036 
0037 #include <Intf_SectionPoint.hxx>
0038 #include <Intf_SectionLine.hxx>
0039 #include <Intf_TangentZone.hxx>
0040 #include <Intf_InterferencePolygon2d.hxx>
0041 
0042 #include <gp_Vec2d.hxx>
0043 
0044 #include <math_Vector.hxx>
0045 #include <math_FunctionSetRoot.hxx>
0046 #include <math_NewtonFunctionSetRoot.hxx>
0047 #include <NCollection_Handle.hxx>
0048 #include <Bnd_Box2d.hxx>
0049 #include <Precision.hxx>
0050 
0051 //======================================================================
0052 
0053 #define NBITER_MAX_POLYGON 10
0054 #define TOL_CONF_MINI   0.0000000001
0055 #define TOL_MINI        0.0000000001
0056 
0057 //----------------------------------------------------------------------
0058 
0059 
0060 void GetIntersection(const TheCurve& theC1, const Standard_Real theT1f, const Standard_Real theT1l,
0061                      const TheCurve& theC2, const Standard_Real theT2f, const Standard_Real theT2l, 
0062                      const Standard_Real theTolConf,
0063                      const Standard_Integer theMaxCount,
0064                      IntRes2d_IntersectionPoint& thePInt, Standard_Real& theDist,
0065                      Standard_Integer& theCount);
0066 
0067 
0068 Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1
0069                                 ,const TheCurve& C1
0070                                 ,const Standard_Real u
0071                                 ,const IntRes2d_Domain& D2
0072                                 ,const TheCurve& C2
0073                                 ,const Standard_Real v
0074                                 ,const Standard_Real TolConf
0075                                 ,IntRes2d_IntersectionPoint& IntPt
0076                                 ,Standard_Boolean& HeadOn1
0077                                 ,Standard_Boolean& HeadOn2
0078                                 ,Standard_Boolean& EndOn1
0079                                 ,Standard_Boolean& EndOn2
0080                                 ,Standard_Integer  PosSegment);
0081 
0082 
0083 //======================================================================
0084 IntCurve_IntPolyPolyGen::IntCurve_IntPolyPolyGen()
0085 {
0086   const Standard_Integer aMinPntNb = 20; // Minimum number of samples.
0087   myMinPntNb = aMinPntNb;
0088   done = Standard_False;
0089 }
0090 //======================================================================
0091 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
0092                                       ,const IntRes2d_Domain& D1
0093                                       ,const TheCurve& C2
0094                                       ,const IntRes2d_Domain& D2
0095                                       ,const Standard_Real TheTolConf
0096                                       ,const Standard_Real TheTol)
0097 {
0098   this->ResetFields();
0099   DomainOnCurve1=D1;
0100   DomainOnCurve2=D2; 
0101   Standard_Real DU = D1.LastParameter()-D1.FirstParameter();
0102   Standard_Real DV = D2.LastParameter()-D2.FirstParameter();
0103   Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol;
0104   Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf;
0105   Perform(C1,D1,C2,D2,TlConf,Tl,0,DU,DV);
0106   //----------------------------------------------------------------------
0107   //-- Processing of end points
0108   //----------------------------------------------------------------------
0109   Standard_Boolean HeadOn1 = Standard_False;
0110   Standard_Boolean HeadOn2 = Standard_False;
0111   Standard_Boolean EndOn1  = Standard_False;
0112   Standard_Boolean EndOn2  = Standard_False;
0113   Standard_Integer i;
0114   Standard_Integer n=this->NbPoints();
0115 
0116 
0117   //--------------------------------------------------------------------
0118   //-- The points Head Head ... End End are not rejected if
0119   //-- they are already present at the end of segment 
0120   //-- ( It is not possible to test the equities on the parameters)
0121   //-- ( these points are not found at EpsX precision    )
0122   //-- PosSegment =            1    if Head Head
0123   //--                       2      if Head End
0124   //--                     4        if End  Head
0125   //--                   8          if End  End
0126   //--------------------------------------------------------------------
0127   Standard_Integer PosSegment = 0;
0128 
0129   for(i=1;i<=n;i++) { 
0130     IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
0131     if(Pos1 == IntRes2d_Head) HeadOn1 = Standard_True;
0132     else if(Pos1 == IntRes2d_End) EndOn1 = Standard_True;
0133 
0134     IntRes2d_Position Pos2 =  this->Point(i).TransitionOfSecond().PositionOnCurve();
0135     if(Pos2 == IntRes2d_Head) HeadOn2 = Standard_True;
0136     else if(Pos2 == IntRes2d_End) EndOn2 = Standard_True;
0137 
0138     if(Pos1 == IntRes2d_Head) { 
0139       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
0140       else if(Pos2 == IntRes2d_End) PosSegment|=2;
0141     }
0142     else if(Pos1 == IntRes2d_End) { 
0143       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
0144       else if(Pos2 == IntRes2d_End) PosSegment|=8;
0145     }
0146   }
0147   
0148   n=this->NbSegments();
0149   for(i=1;i<=n;i++) { 
0150     IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
0151     if(Pos1 == IntRes2d_Head)     HeadOn1 = Standard_True;
0152     else if(Pos1 == IntRes2d_End) EndOn1  = Standard_True;
0153     
0154     IntRes2d_Position Pos2 =  this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
0155     if(Pos2 == IntRes2d_Head)      HeadOn2 = Standard_True;
0156     else if(Pos2 == IntRes2d_End)  EndOn2  = Standard_True;
0157 
0158     if(Pos1 == IntRes2d_Head) { 
0159       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
0160       else if(Pos2 == IntRes2d_End) PosSegment|=2;
0161     }
0162     else if(Pos1 == IntRes2d_End) { 
0163       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
0164       else if(Pos2 == IntRes2d_End) PosSegment|=8;
0165     }
0166 
0167     Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
0168     if(Pos1 == IntRes2d_Head)     HeadOn1 = Standard_True;
0169     else if(Pos1 == IntRes2d_End) EndOn1  = Standard_True;
0170     
0171     Pos2 =  this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
0172     if(Pos2 == IntRes2d_Head)     HeadOn2 = Standard_True;
0173     else if(Pos2 == IntRes2d_End) EndOn2  = Standard_True;
0174 
0175     if(Pos1 == IntRes2d_Head) { 
0176       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
0177       else if(Pos2 == IntRes2d_End) PosSegment|=2;
0178     }
0179     else if(Pos1 == IntRes2d_End) { 
0180       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
0181       else if(Pos2 == IntRes2d_End) PosSegment|=8;
0182     }
0183   }
0184 
0185   Standard_Real U0 = D1.FirstParameter();
0186   Standard_Real U1 = D1.LastParameter();
0187   Standard_Real V0 = D2.FirstParameter();
0188   Standard_Real V1 = D2.LastParameter();
0189   IntRes2d_IntersectionPoint IntPt;
0190   
0191   if(D1.FirstTolerance() || D2.FirstTolerance()) { 
0192     if(HeadOrEndPoint(D1,C1,U0,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) 
0193       this->Insert(IntPt);
0194   }
0195   if(D1.FirstTolerance() || D2.LastTolerance()) { 
0196     if(HeadOrEndPoint(D1,C1,U0,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) 
0197       this->Insert(IntPt);
0198   }
0199   if(D1.LastTolerance() || D2.FirstTolerance()) {
0200     if(HeadOrEndPoint(D1,C1,U1,D2,C2,V0,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) 
0201       this->Insert(IntPt);
0202   }
0203   if(D1.LastTolerance() ||  D2.LastTolerance()) { 
0204     if(HeadOrEndPoint(D1,C1,U1,D2,C2,V1,TheTolConf,IntPt,HeadOn1,HeadOn2,EndOn1,EndOn2,PosSegment)) 
0205       this->Insert(IntPt);
0206   }
0207 }
0208 
0209 
0210 //======================================================================
0211 //==      A u t o   I n t e r s e c t i o  n 
0212 //======================================================================
0213 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
0214                                       ,const IntRes2d_Domain& D1
0215                                       ,const Standard_Real TheTolConf
0216                                       ,const Standard_Real TheTol)
0217 {
0218 
0219   this->ResetFields();
0220   DomainOnCurve1=D1;
0221   DomainOnCurve2=D1; 
0222   Standard_Real DU = D1.LastParameter()-D1.FirstParameter();
0223   Standard_Real Tl=(TheTol < TOL_MINI)? TOL_MINI : TheTol;
0224   Standard_Real TlConf=(TheTolConf < TOL_CONF_MINI)? TOL_CONF_MINI : TheTolConf;
0225   Perform(C1,D1,TlConf,Tl,0,DU,DU);
0226   Standard_Integer i;
0227   Standard_Integer n=this->NbPoints();
0228 
0229   //--------------------------------------------------------------------
0230    //-- The points Head Head ... End End are not rejected if
0231   //-- they are already present at the end of segment 
0232   //-- ( It is not possible to test the equities on the parameters)
0233   //-- ( these points are not found at EpsX precision    )
0234   //-- PosSegment =            1    if Head Head
0235   //--                       2      if Head End
0236   //--                     4        if End  Head
0237   //--                   8          if End  End
0238   //--------------------------------------------------------------------
0239   Standard_Integer PosSegment = 0;
0240 
0241   for(i=1;i<=n;i++) { 
0242     IntRes2d_Position Pos1 = this->Point(i).TransitionOfFirst().PositionOnCurve();
0243     IntRes2d_Position Pos2 =  this->Point(i).TransitionOfSecond().PositionOnCurve();
0244 
0245     if(Pos1 == IntRes2d_Head) { 
0246       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
0247       else if(Pos2 == IntRes2d_End) PosSegment|=2;
0248     }
0249     else if(Pos1 == IntRes2d_End) { 
0250       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
0251       else if(Pos2 == IntRes2d_End) PosSegment|=8;
0252     }
0253   }
0254   
0255   n=this->NbSegments();
0256   for(i=1;i<=n;i++) { 
0257     IntRes2d_Position Pos1 = this->Segment(i).FirstPoint().TransitionOfFirst().PositionOnCurve();
0258     IntRes2d_Position Pos2 =  this->Segment(i).FirstPoint().TransitionOfSecond().PositionOnCurve();
0259 
0260     if(Pos1 == IntRes2d_Head) { 
0261       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
0262       else if(Pos2 == IntRes2d_End) PosSegment|=2;
0263     }
0264     else if(Pos1 == IntRes2d_End) { 
0265       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
0266       else if(Pos2 == IntRes2d_End) PosSegment|=8;
0267     }
0268 
0269     Pos1 = this->Segment(i).LastPoint().TransitionOfFirst().PositionOnCurve();
0270     Pos2 =  this->Segment(i).LastPoint().TransitionOfSecond().PositionOnCurve();
0271 
0272     if(Pos1 == IntRes2d_Head) { 
0273       if(Pos2 == IntRes2d_Head)     PosSegment|=1;
0274       else if(Pos2 == IntRes2d_End) PosSegment|=2;
0275     }
0276     else if(Pos1 == IntRes2d_End) { 
0277       if(Pos2 == IntRes2d_Head)     PosSegment|=4;
0278       else if(Pos2 == IntRes2d_End) PosSegment|=8;
0279     }
0280   }
0281   (void )PosSegment;
0282 }
0283 //======================================================================
0284 
0285 void IntCurve_IntPolyPolyGen::Perform( const TheCurve& C1
0286                                       ,const IntRes2d_Domain& D1
0287                                       ,const Standard_Real TolConf
0288                                       ,const Standard_Real Tol
0289                                       ,const Standard_Integer NbIter
0290                                       ,const Standard_Real /*DeltaU*/
0291                                       ,const Standard_Real) {
0292   
0293   gp_Vec2d Tan1,Tan2,Norm1,Norm2;
0294   gp_Pnt2d P1,P2;
0295   Standard_Integer nbsamples;
0296   done = Standard_False;
0297   
0298   nbsamples = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
0299 
0300   if(NbIter>3 || (NbIter>2 && nbsamples>100)) return;
0301 
0302   nbsamples*=2;   //---  We take systematically two times more points 
0303                   //--   than on a normal curve.  
0304                   //--   Auto-intersecting curves often produce  
0305                   //--   polygons rather far from the curve with parameter ct.
0306 
0307   if(NbIter>0) { 
0308     nbsamples=(3*(nbsamples*NbIter))/2;
0309   }
0310   IntCurve_ThePolygon2d Poly1(C1,nbsamples,D1,Tol);
0311   if(!Poly1.AutoIntersectionIsPossible()) { 
0312     done = Standard_True;
0313     return;
0314   }
0315   //-- Poly1.Dump();
0316   //----------------------------------------------------------------------
0317   //-- If the deflection is less than the Tolerance of Confusion
0318   //-- then the deflection of the polygon is set in TolConf
0319   //-- (Detection of Tangency Zones)
0320   //----------------------------------------------------------------------
0321   if(Poly1.DeflectionOverEstimation() < TolConf) { 
0322     Poly1.SetDeflectionOverEstimation(TolConf);
0323   }
0324 
0325   Intf_InterferencePolygon2d InterPP(Poly1);  
0326   IntCurve_ExactIntersectionPoint  EIP(C1,C1,TolConf);
0327   Standard_Real U,V;
0328   
0329   //----------------------------------------------------------------------
0330   //-- Processing of SectionPoint 
0331   //----------------------------------------------------------------------
0332   Standard_Integer Nbsp = InterPP.NbSectionPoints();
0333   if(Nbsp>=1) {
0334     
0335     //-- ---------------------------------------------------------------------
0336     //-- filtering, filtering, filtering ...
0337     //-- 
0338     Standard_Integer* TriIndex     = new Standard_Integer [Nbsp+1];
0339     Standard_Integer* PtrSegIndex1 = new Standard_Integer [Nbsp+1];
0340     Standard_Integer* PtrSegIndex2 = new Standard_Integer [Nbsp+1];
0341     Standard_Boolean Triok;
0342     Standard_Integer SegIndex1,SegIndex2,SegIndex_1,SegIndex_2;
0343 //    Standard_Real    ParamOn1,ParamOn2,ParamOn_1,ParamOn_2;
0344     Standard_Real    ParamOn1,ParamOn2;
0345     Intf_PIType      Type; 
0346     Standard_Integer i ;
0347     for( i=1;i<=Nbsp;i++) { 
0348       TriIndex[i]=i;
0349       const Intf_SectionPoint& SPnt1 = InterPP.PntValue(i);
0350       SPnt1.InfoFirst(Type,PtrSegIndex1[i],ParamOn1);
0351       SPnt1.InfoSecond(Type,PtrSegIndex2[i],ParamOn2);
0352     }
0353  
0354 
0355     do { 
0356       Triok=Standard_True;
0357 
0358       for(Standard_Integer tr=1;tr<Nbsp;tr++) { 
0359               SegIndex1=PtrSegIndex1[TriIndex[tr]];
0360               SegIndex_1=PtrSegIndex1[TriIndex[tr+1]];
0361 
0362               SegIndex2=PtrSegIndex2[TriIndex[tr]];
0363               SegIndex_2=PtrSegIndex2[TriIndex[tr+1]];
0364 
0365               if(SegIndex1 > SegIndex_1) { 
0366                 Standard_Integer q=TriIndex[tr]; 
0367                 TriIndex[tr]=TriIndex[tr+1];
0368                 TriIndex[tr+1]=q;
0369                 Triok=Standard_False;
0370               }
0371               else if(SegIndex1 == SegIndex_1) { 
0372                 if(SegIndex2 > SegIndex_2) { 
0373                   Standard_Integer q=TriIndex[tr]; 
0374                   TriIndex[tr]=TriIndex[tr+1];
0375                   TriIndex[tr+1]=q;
0376                   Triok=Standard_False;
0377                 }
0378               }
0379       }
0380     }
0381     while(Triok==Standard_False);
0382 
0383     //-- supression des doublons Si Si !
0384     for(i=1; i<Nbsp;i++) { 
0385       if(   (PtrSegIndex1[TriIndex[i]] == PtrSegIndex1[TriIndex[i+1]])
0386                 && (PtrSegIndex2[TriIndex[i]] == PtrSegIndex2[TriIndex[i+1]])) { 
0387               TriIndex[i]=-i;
0388       }
0389     }
0390 
0391     for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
0392       if(TriIndex[sp]>0) { 
0393               const Intf_SectionPoint& SPnt = InterPP.PntValue(TriIndex[sp]);
0394         
0395               SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
0396               SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
0397         
0398               if(Abs(SegIndex1-SegIndex2)>1) { 
0399           
0400                 EIP.Perform(Poly1,Poly1,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
0401                 if(EIP.NbRoots()>=1) { 
0402                   //--------------------------------------------------------------------
0403                   //-- It is checked if the found point is a root
0404                   //--------------------------------------------------------------------
0405                   EIP.Roots(U,V);
0406 
0407                   TheCurveTool::D1(C1,U,P1,Tan1);
0408                   TheCurveTool::D1(C1,V,P2,Tan2);
0409                   Standard_Real Dist = P1.Distance(P2);
0410                   Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1);
0411             
0412                   if(Abs(U-V)<=EpsX1) { 
0413                     //-----------------------------------------
0414                     //-- Solution not valid 
0415                     //-- The maths should have converged in a 
0416                     //-- trivial solution  ( point U = V )
0417                     //-----------------------------------------
0418                     Dist = TolConf+1.0;
0419                   }
0420             
0421                   //-----------------------------------------------------------------
0422                   //-- It is checked if the point (u,v) already exists  
0423                   //--
0424                   done = Standard_True;
0425                   Standard_Integer nbp=NbPoints();
0426             
0427                   for(Standard_Integer p=1; p<=nbp; p++) { 
0428                     const IntRes2d_IntersectionPoint& P=Point(p);
0429                     if(Abs(U-P.ParamOnFirst()) <= EpsX1) { 
0430                             if(Abs(V-P.ParamOnSecond()) <= EpsX1) { 
0431                               Dist = TolConf+1.0;  p+=nbp;
0432                             }
0433                     }
0434                   }
0435             
0436                   if(Dist <= TolConf) {    //-- Or the point is already present
0437                     IntRes2d_Position Pos1 = IntRes2d_Middle;
0438                     IntRes2d_Position Pos2 = IntRes2d_Middle;
0439                     IntRes2d_Transition  Trans1,Trans2;
0440                     //-----------------------------------------------------------------
0441                     //-- Calculate Positions of Points on the curve
0442                     //--
0443                     if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    
0444                             Pos1 = IntRes2d_Head;
0445                     else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) 
0446                             Pos1 = IntRes2d_End;
0447               
0448                     if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    
0449                             Pos2 = IntRes2d_Head;
0450                     else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) 
0451                             Pos2 = IntRes2d_End;
0452                     //-----------------------------------------------------------------
0453                     if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1
0454                                                          ,Pos2,Tan2,Trans2
0455                                                          ,TolConf) == Standard_False) 
0456               {
0457                             TheCurveTool::D2(C1,U,P1,Tan1,Norm1);
0458                             TheCurveTool::D2(C1,V,P2,Tan2,Norm2);
0459                             IntImpParGen::DetermineTransition( Pos1,Tan1,Norm1,Trans1
0460                                                               ,Pos2,Tan2,Norm2,Trans2
0461                                                               ,TolConf);
0462                     }
0463                     IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
0464                     Insert(IP);
0465                   }
0466                 }
0467               }
0468       }
0469     }
0470     delete [] TriIndex;
0471     delete [] PtrSegIndex1;
0472     delete [] PtrSegIndex2;
0473   }
0474 
0475   //----------------------------------------------------------------------
0476   //-- Processing of TangentZone
0477   //----------------------------------------------------------------------
0478   Standard_Integer Nbtz = InterPP.NbTangentZones();
0479   for(Standard_Integer tz=1; tz <= Nbtz; tz++) {
0480     Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
0481     //====================================================================
0482     //== Find the first and the last point in the tangency zone.
0483     //====================================================================
0484     Standard_Real ParamSupOnCurve2,ParamInfOnCurve2;
0485     Standard_Real ParamSupOnCurve1,ParamInfOnCurve1;
0486 //    Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2;
0487     Standard_Integer SegIndex1onP1,SegIndex1onP2;
0488     Intf_PIType Type;
0489     Standard_Real ParamOnLine;
0490     Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup;
0491     ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast();
0492     ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast();
0493     for(Standard_Integer qq=1;qq<=NbPnts;qq++) { 
0494       const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
0495       //====================================================================
0496       //== The zones of tangency are discretized 
0497       //== Test of stop : Check if 
0498       //==     (Deflection  < Tolerance)
0499       //==  Or (Sample < EpsX)   (normally the first condition is 
0500       //==                           more strict)
0501       //====================================================================
0502 //      Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup;
0503       Standard_Real _PolyUInf,_PolyVInf;
0504 
0505       SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine);
0506       if(SegIndex1onP1 > Poly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; }
0507       if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; }
0508       _PolyUInf = Poly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine);
0509       
0510       SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine);
0511       if(SegIndex1onP2 > Poly1.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; }
0512       if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; }
0513       _PolyVInf = Poly1.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine);
0514       
0515       //----------------------------------------------------------------------
0516 
0517       if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf;
0518       if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf;
0519 
0520       if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf;
0521       if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf;
0522     }
0523 
0524     PolyUInf= ParamInfOnCurve1;
0525     PolyUSup= ParamSupOnCurve1;
0526     PolyVInf= ParamInfOnCurve2;
0527     PolyVSup= ParamSupOnCurve2;
0528     
0529     TheCurveTool::D0(C1,PolyUInf,P1);
0530     TheCurveTool::D0(C1,PolyVInf,P2);
0531     Standard_Real distmemesens = P1.SquareDistance(P2);
0532     TheCurveTool::D0(C1,PolyVSup,P2);
0533     Standard_Real distdiffsens = P1.SquareDistance(P2);
0534     if(distmemesens > distdiffsens) { 
0535       Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty;
0536     }
0537 
0538     //-----------------------------------------------------------------
0539     //-- Calculate Positions of Points on the curve and  
0540     //-- Transitions on each limit of the segment
0541     
0542     IntRes2d_Position Pos1 = IntRes2d_Middle;
0543     IntRes2d_Position Pos2 = IntRes2d_Middle;
0544     IntRes2d_Transition  Trans1,Trans2;
0545     
0546     TheCurveTool::D1(C1,PolyUInf,P1,Tan1);
0547     TheCurveTool::D1(C1,PolyVInf,P2,Tan2);
0548     
0549     if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    { 
0550       Pos1 = IntRes2d_Head;
0551     }
0552     else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { 
0553       Pos1 = IntRes2d_End;  
0554     }
0555     if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    { 
0556       Pos2 = IntRes2d_Head; 
0557     }
0558     else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { 
0559       Pos2 = IntRes2d_End;  
0560     }
0561     
0562     if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { 
0563       PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0564     }
0565     else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { 
0566       PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0567     }
0568     else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { 
0569       PolyVInf=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0570     }
0571     else { 
0572       PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0573     }
0574     
0575 
0576     
0577     if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf) 
0578        == Standard_False)
0579     {
0580       TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1);
0581       TheCurveTool::D2(C1,PolyVInf,P2,Tan2,Norm2);
0582       IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
0583                                         Pos2,Tan2,Norm2,Trans2,TolConf);
0584     }
0585     IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf
0586                                         ,Trans1,Trans2,Standard_False);
0587     //----------------------------------------------------------------------
0588     
0589     if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1)) ||
0590        (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C1)))
0591     { 
0592       //bad segment
0593     }
0594     else 
0595     { 
0596       TheCurveTool::D1(C1,PolyUSup,P1,Tan1);
0597       TheCurveTool::D1(C1,PolyVSup,P2,Tan2);
0598       Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle;
0599       
0600       if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    { 
0601         Pos1 = IntRes2d_Head; 
0602       }
0603       else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { 
0604         Pos1 = IntRes2d_End;  
0605       }
0606       if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    { 
0607         Pos2 = IntRes2d_Head; 
0608       }
0609       else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { 
0610         Pos2 = IntRes2d_End;  
0611       }
0612       
0613       
0614       if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { 
0615         PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0616       }
0617       else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { 
0618         PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0619       }
0620       else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { 
0621         PolyVSup=TheProjPCur::FindParameter( C1,P1,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0622       }
0623       else { 
0624         PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
0625       }
0626       
0627       if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
0628          ==Standard_False) { 
0629         TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1);
0630         TheCurveTool::D2(C1,PolyVSup,P2,Tan2,Norm2);
0631         IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
0632                                           Pos2,Tan2,Norm2,Trans2,TolConf);
0633       }
0634       IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup
0635                                         ,Trans1,Trans2,Standard_False);
0636       
0637       Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True;
0638       if(ParamInfOnCurve1 > ParamSupOnCurve1) {
0639         IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False);
0640         Append(Seg);
0641       }
0642       else { 
0643         IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False);
0644         Append(Seg);
0645       }
0646     }
0647   } //end of processing of TangentZone
0648   
0649  done = Standard_True;
0650 }
0651 
0652 
0653 Standard_Boolean HeadOrEndPoint( const IntRes2d_Domain& D1
0654                                 ,const TheCurve& C1
0655                                 ,const Standard_Real tu
0656                                 ,const IntRes2d_Domain& D2
0657                                 ,const TheCurve& C2
0658                                 ,const Standard_Real tv
0659                                 ,const Standard_Real TolConf
0660                                 ,IntRes2d_IntersectionPoint& IntPt
0661                                 ,Standard_Boolean& HeadOn1
0662                                 ,Standard_Boolean& HeadOn2
0663                                 ,Standard_Boolean& EndOn1
0664                                 ,Standard_Boolean& EndOn2
0665                                 ,Standard_Integer PosSegment) { 
0666 
0667   gp_Pnt2d P1,P2,SP1,SP2;
0668   gp_Vec2d T1,T2,N1,N2;
0669   Standard_Real u=tu;
0670   Standard_Real v=tv;
0671   Standard_Real svu = u;
0672   Standard_Real svv = v;
0673 
0674   TheCurveTool::D1(C1,u,P1,T1);
0675   TheCurveTool::D1(C2,v,P2,T2);
0676   
0677   IntRes2d_Position Pos1 = IntRes2d_Middle; 
0678   IntRes2d_Position Pos2 = IntRes2d_Middle;
0679   IntRes2d_Transition Trans1,Trans2;
0680 
0681   //----------------------------------------------------------------------
0682   //-- Head On 1   :        Head1 <-> P2
0683   if(P2.Distance(D1.FirstPoint())<=D1.FirstTolerance())    { 
0684     Pos1 = IntRes2d_Head; 
0685     HeadOn1 = Standard_True; 
0686     SP1 = D1.FirstPoint();
0687     u = D1.FirstParameter();
0688   }
0689   //----------------------------------------------------------------------
0690   //-- End On 1   :         End1 <-> P2
0691   else if(P2.Distance(D1.LastPoint())<=D1.LastTolerance()) { 
0692     Pos1 = IntRes2d_End; 
0693     EndOn1 = Standard_True;
0694     SP1 = D1.LastPoint();
0695     u = D1.LastParameter();
0696   }
0697 
0698   //----------------------------------------------------------------------
0699   //-- Head On 2   :        Head2 <-> P1
0700   else if(P1.Distance(D2.FirstPoint())<=D2.FirstTolerance())    { 
0701     Pos2 = IntRes2d_Head; 
0702     HeadOn2 = Standard_True; 
0703     SP2 = D2.FirstPoint();
0704     v = D2.FirstParameter();
0705   }
0706   //----------------------------------------------------------------------
0707   //-- End On 2   :        End2 <-> P1
0708   else if(P1.Distance(D2.LastPoint())<=D2.LastTolerance()) { 
0709     Pos2 = IntRes2d_End; 
0710     EndOn2 = Standard_True;
0711     SP2 = D2.LastPoint();
0712     v = D2.LastParameter();
0713   }
0714 
0715   Standard_Real EpsX1 = TheCurveTool::EpsX(C1);
0716   Standard_Real EpsX2 = TheCurveTool::EpsX(C2);
0717 
0718   if((Pos1 != IntRes2d_Middle)||(Pos2 !=  IntRes2d_Middle)) { 
0719     if(Pos1 == IntRes2d_Middle) {
0720       if(Abs(u-D1.FirstParameter()) <= EpsX1) { 
0721               Pos1 = IntRes2d_Head;
0722               P1 = D1.FirstPoint();
0723               HeadOn1 = Standard_True;
0724       }
0725       else if(Abs(u-D1.LastParameter()) <= EpsX1) { 
0726               Pos1 = IntRes2d_End;
0727               P1 = D1.LastPoint();
0728               EndOn1 = Standard_True;
0729       }
0730     }
0731     else if(u!=tu) {
0732       P1 = SP1; 
0733     }
0734       
0735     
0736     if(Pos2 == IntRes2d_Middle) { 
0737       if(Abs(v-D2.FirstParameter()) <= EpsX2) { 
0738               Pos2 = IntRes2d_Head;
0739               HeadOn2 = Standard_True;
0740               P2 = D2.FirstPoint();     
0741               if(Pos1 != IntRes2d_Middle) {
0742                 P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y()));
0743               }
0744               else { 
0745                 P2 = P1; 
0746               }
0747       }
0748       else if(Abs(v-D2.LastParameter()) <= EpsX2) { 
0749               Pos2 = IntRes2d_End;
0750               EndOn2 = Standard_True;
0751               P2 = D2.LastPoint();
0752               if(Pos1 != IntRes2d_Middle) {
0753                 P1.SetCoord(0.5*(P1.X()+P2.X()),0.5*(P1.Y()+P2.Y()));
0754               }
0755               else { 
0756                 P2 = P1; 
0757               }
0758       }
0759     }
0760 
0761     //--------------------------------------------------------------------
0762     //-- It is tested if a point at the end of segment already has its transitions
0763     //-- If Yes, the new point is not created
0764     //-- 
0765     //-- PosSegment =            1    if Head Head
0766     //--                       2      if Head End
0767     //--                     4        if End  Head
0768     //--                   8          if End  End
0769     //--------------------------------------------------------------------
0770     if(Pos1 == IntRes2d_Head) { 
0771       if((Pos2 == IntRes2d_Head)&&(PosSegment & 1)) return(Standard_False);
0772       if((Pos2 == IntRes2d_End )&&(PosSegment & 2)) return(Standard_False);
0773     }
0774     else if(Pos1 == IntRes2d_End) { 
0775       if((Pos2 == IntRes2d_Head)&&(PosSegment & 4)) return(Standard_False);
0776       if((Pos2 == IntRes2d_End )&&(PosSegment & 8)) return(Standard_False);
0777     }
0778 
0779 
0780     if(IntImpParGen::DetermineTransition( Pos1,T1,Trans1,Pos2,T2,Trans2,TolConf)
0781        == Standard_False) { 
0782       TheCurveTool::D2(C1,svu,P1,T1,N1);
0783       TheCurveTool::D2(C2,svv,P2,T2,N2);
0784       IntImpParGen::DetermineTransition(Pos1,T1,N1,Trans1,
0785                                         Pos2,T2,N2,Trans2,TolConf);
0786     }
0787     IntPt.SetValues(P1,u,v,Trans1,Trans2,Standard_False);
0788     return(Standard_True);
0789   }
0790   else 
0791     return(Standard_False);
0792 }
0793 
0794 //=======================================================================
0795 //function : Perform
0796 //purpose  : Base method to perform polyline / polyline intersection for
0797 //           pair of curves.
0798 //=======================================================================
0799 void IntCurve_IntPolyPolyGen::Perform(const TheCurve& C1,
0800                                       const IntRes2d_Domain& D1,
0801                                       const TheCurve& C2,
0802                                       const IntRes2d_Domain& D2,
0803                                       const Standard_Real TolConf,
0804                                       const Standard_Real Tol,
0805                                       const Standard_Integer NbIter,
0806                                       const Standard_Real DeltaU,
0807                                       const Standard_Real DeltaV)
0808 {
0809   Standard_Integer nbsamplesOnC1,nbsamplesOnC2;
0810   done = Standard_False;
0811 
0812   if(NbIter>NBITER_MAX_POLYGON) return;
0813 
0814   // Number of samples running.
0815   nbsamplesOnC1 = TheCurveTool::NbSamples(C1,D1.FirstParameter(),D1.LastParameter());
0816   nbsamplesOnC2 = TheCurveTool::NbSamples(C2,D2.FirstParameter(),D2.LastParameter());
0817 
0818   if (NbIter == 0)
0819   {
0820     // Minimal number of points.
0821     nbsamplesOnC1 = Max(nbsamplesOnC1, myMinPntNb);
0822     nbsamplesOnC2 = Max(nbsamplesOnC2, myMinPntNb);
0823   }
0824   else
0825   {
0826     // Increase number of samples in second and next iterations.
0827     nbsamplesOnC1=(5 * (nbsamplesOnC1 * NbIter)) / 4;
0828     nbsamplesOnC2=(5 * (nbsamplesOnC2 * NbIter)) / 4;
0829   }
0830 
0831   NCollection_Handle<IntCurve_ThePolygon2d>
0832     aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol),
0833     aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
0834 
0835   if( (aPoly1->DeflectionOverEstimation() > TolConf) &&
0836       (aPoly2->DeflectionOverEstimation() > TolConf))
0837   {
0838     const Standard_Real aDeflectionSum = 
0839       Max(aPoly1->DeflectionOverEstimation(), TolConf) + 
0840       Max(aPoly2->DeflectionOverEstimation(), TolConf);
0841 
0842     if (nbsamplesOnC2 > nbsamplesOnC1)
0843     {
0844       aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
0845       aPoly1->SetDeflectionOverEstimation(aDeflectionSum);
0846       aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
0847     }
0848     else
0849     {
0850       aPoly1->ComputeWithBox(C1, aPoly2->Bounding());
0851       aPoly2->SetDeflectionOverEstimation(aDeflectionSum);
0852       aPoly2->ComputeWithBox(C2, aPoly1->Bounding());
0853     }
0854   }
0855 
0856   //----------------------------------------------------------------------
0857   //-- if the deflection less then the Tolerance of Confusion
0858   //-- Then the deflection of the polygon is set in TolConf
0859   //-- (Detection of Tangency Zones)
0860   //----------------------------------------------------------------------
0861 
0862   if(aPoly1->DeflectionOverEstimation() < TolConf) { 
0863     aPoly1->SetDeflectionOverEstimation(TolConf);
0864   }
0865   if(aPoly2->DeflectionOverEstimation() < TolConf) { 
0866     aPoly2->SetDeflectionOverEstimation(TolConf);
0867   }
0868   // for case when a few polygon points were replaced by line
0869   // if exact solution was not found 
0870   // then search of precise solution will be repeated 
0871   // for polygon contains all initial points
0872   // secondary search will be performed only for case when initial points
0873   // were dropped
0874   Standard_Boolean isFullRepresentation = ( aPoly1->NbSegments() == nbsamplesOnC1 && 
0875             aPoly2->NbSegments() == nbsamplesOnC2 );
0876   
0877   if( !findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
0878           DeltaU, DeltaV, *aPoly1, *aPoly2, isFullRepresentation ) && !isFullRepresentation ) 
0879   {
0880     if(aPoly1->NbSegments() < nbsamplesOnC1)
0881     {
0882       aPoly1 = new IntCurve_ThePolygon2d(C1,nbsamplesOnC1,D1,Tol);
0883     }
0884     if(aPoly2->NbSegments() < nbsamplesOnC2)
0885     {
0886       aPoly2 = new IntCurve_ThePolygon2d(C2,nbsamplesOnC2,D2,Tol);
0887     }
0888 
0889     findIntersect( C1, D1, C2, D2, TolConf, Tol, NbIter,
0890       DeltaU, DeltaV, *aPoly1, *aPoly2, 
0891       Standard_True);   
0892 
0893   }
0894  
0895   done = Standard_True;
0896 }
0897 
0898 //======================================================================
0899 // Purpose : findIntersect
0900 //======================================================================
0901 
0902 Standard_Boolean IntCurve_IntPolyPolyGen::findIntersect( 
0903     const TheCurve& C1,
0904           const IntRes2d_Domain& D1,
0905           const TheCurve& C2,
0906           const IntRes2d_Domain& D2,
0907           const Standard_Real TolConf,
0908           const Standard_Real Tol,
0909           const Standard_Integer NbIter,
0910           const Standard_Real DeltaU,
0911           const Standard_Real DeltaV,
0912           const IntCurve_ThePolygon2d& thePoly1,
0913           const IntCurve_ThePolygon2d& thePoly2,
0914           Standard_Boolean isFullPolygon )
0915 {
0916 
0917   gp_Vec2d Tan1,Tan2,Norm1,Norm2;
0918   gp_Pnt2d P1,P2;
0919   Intf_InterferencePolygon2d InterPP(thePoly1,thePoly2);  
0920   IntCurve_ExactIntersectionPoint  EIP(C1,C2,TolConf);
0921   Standard_Real U = 0., V = 0.;
0922   Standard_Boolean AnErrorOccurred = Standard_False;
0923   done = Standard_True; // To prevent exception in nbp=NbPoints();
0924   //----------------------------------------------------------------------
0925   //-- Processing of SectionPoint 
0926   //----------------------------------------------------------------------
0927   Standard_Integer Nbsp = InterPP.NbSectionPoints();
0928   for(Standard_Integer sp=1; sp <= Nbsp; sp++) {
0929     const Intf_SectionPoint& SPnt = InterPP.PntValue(sp);
0930     Standard_Integer SegIndex1,SegIndex2;
0931     Standard_Real    ParamOn1,ParamOn2;
0932     Intf_PIType      Type;
0933 
0934     SPnt.InfoFirst(Type,SegIndex1,ParamOn1);
0935     SPnt.InfoSecond(Type,SegIndex2,ParamOn2);
0936     EIP.Perform(thePoly1,thePoly2,SegIndex1,SegIndex2,ParamOn1,ParamOn2);
0937     AnErrorOccurred = EIP.AnErrorOccurred();
0938 
0939     if( !EIP.NbRoots() && !isFullPolygon)
0940       return Standard_False;
0941 
0942     if(AnErrorOccurred) 
0943     {
0944       continue;
0945     }
0946 
0947     //--------------------------------------------------------------------
0948     //-- It is checked if the found point is really a root
0949     //--------------------------------------------------------------------
0950 
0951     EIP.Roots(U,V);
0952     TheCurveTool::D1(C1,U,P1,Tan1);
0953     TheCurveTool::D1(C2,V,P2,Tan2);
0954     Standard_Real Dist = P1.Distance(P2);
0955     if(EIP.NbRoots() == 0 && Dist > TolConf)
0956     {
0957       IntRes2d_Transition aTrans;
0958       IntRes2d_IntersectionPoint aPInt(P1, U, V, aTrans, aTrans, Standard_False);
0959       Standard_Real aT1f, aT1l, aT2f, aT2l;
0960       aT1f= thePoly1.ApproxParamOnCurve(SegIndex1, 0.0); 
0961       aT1l= thePoly1.ApproxParamOnCurve(SegIndex1, 1.0); 
0962       aT2f= thePoly2.ApproxParamOnCurve(SegIndex2, 0.0); 
0963       aT2l= thePoly2.ApproxParamOnCurve(SegIndex2, 1.0); 
0964       //
0965       Standard_Integer aMaxCount = 16, aCount = 0;
0966       GetIntersection(C1, aT1f, aT1l, C2, aT2f, aT2l, TolConf, aMaxCount, 
0967                       aPInt, Dist, aCount); 
0968       U = aPInt.ParamOnFirst();
0969       V = aPInt.ParamOnSecond();
0970       TheCurveTool::D1(C1,U,P1,Tan1);
0971       TheCurveTool::D1(C2,V,P2,Tan2);
0972       Dist = P1.Distance(P2);
0973     }
0974     //-----------------------------------------------------------------
0975     //-- It is checked if the point (u,v) does not exist already 
0976     //--
0977     Standard_Integer nbp=NbPoints();
0978     Standard_Real EpsX1 = 10.0*TheCurveTool::EpsX(C1);
0979     Standard_Real EpsX2 = 10.0*TheCurveTool::EpsX(C2);
0980     for(Standard_Integer p=1; p<=nbp; p++) { 
0981       const IntRes2d_IntersectionPoint& P=Point(p);
0982       if(Abs(U-P.ParamOnFirst()) <= EpsX1) { 
0983         if(Abs(V-P.ParamOnSecond()) <= EpsX2) { 
0984           Dist = TolConf+1.0;  p+=nbp;
0985         }
0986       }
0987     }
0988 
0989     if(Dist <= TolConf) {    //-- Or the point is already present
0990       IntRes2d_Position Pos1 = IntRes2d_Middle;
0991       IntRes2d_Position Pos2 = IntRes2d_Middle;
0992       IntRes2d_Transition  Trans1,Trans2;
0993       //-----------------------------------------------------------------
0994       //-- Calculate the Positions of Points on the curve
0995       //--
0996       if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    
0997         Pos1 = IntRes2d_Head;
0998       else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) 
0999         Pos1 = IntRes2d_End;
1000 
1001       if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    
1002         Pos2 = IntRes2d_Head;
1003       else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) 
1004         Pos2 = IntRes2d_End;
1005       //-----------------------------------------------------------------
1006       //-- Calculate the Transitions (see IntImpParGen.cxx)
1007       //--
1008       if(IntImpParGen::DetermineTransition (Pos1, Tan1, Trans1, Pos2, Tan2, Trans2, TolConf) == Standard_False) { 
1009         TheCurveTool::D2(C1,U,P1,Tan1,Norm1);
1010         TheCurveTool::D2(C2,V,P2,Tan2,Norm2);
1011         IntImpParGen::DetermineTransition (Pos1, Tan1, Norm1, Trans1, Pos2, Tan2, Norm2, Trans2, TolConf);
1012       }
1013       IntRes2d_IntersectionPoint IP(P1,U,V,Trans1,Trans2,Standard_False);
1014       Insert(IP);
1015     }
1016   }
1017   
1018   //----------------------------------------------------------------------
1019   //-- Processing of TangentZone
1020   //----------------------------------------------------------------------
1021   Standard_Integer Nbtz = InterPP.NbTangentZones();
1022   for(Standard_Integer tz=1; tz <= Nbtz; tz++) {
1023     Standard_Integer NbPnts = InterPP.ZoneValue(tz).NumberOfPoints();
1024     //====================================================================
1025     //== Find the first and the last point in the tangency zone.
1026     //====================================================================
1027     Standard_Real ParamSupOnCurve2,ParamInfOnCurve2;
1028     Standard_Real ParamSupOnCurve1,ParamInfOnCurve1;
1029 //    Standard_Integer SegIndex,SegIndex1onP1,SegIndex1onP2,SegIndex2onP1,SegIndex2onP2;
1030     Standard_Integer SegIndex1onP1,SegIndex1onP2;
1031     Intf_PIType Type;
1032     Standard_Real ParamOnLine;
1033     Standard_Real PolyUInf,PolyUSup,PolyVInf,PolyVSup;
1034     ParamSupOnCurve2=ParamSupOnCurve1=PolyUSup=PolyVSup=-RealLast();
1035     ParamInfOnCurve2=ParamInfOnCurve1=PolyUInf=PolyVInf= RealLast();
1036     for(Standard_Integer qq=1;qq<=NbPnts;qq++) { 
1037       const Intf_SectionPoint& SPnt1 = InterPP.ZoneValue(tz).GetPoint(qq);
1038       //====================================================================
1039       //== The zones of tangency are discretized 
1040       //== Test of stop : Check if 
1041       //==     (Deflection  < Tolerance)
1042       //==  Or (Sample < EpsX)   (normally the first condition is 
1043       //==                           more strict)
1044       //====================================================================
1045 //      Standard_Real _PolyUInf,_PolyUSup,_PolyVInf,_PolyVSup;
1046       Standard_Real _PolyUInf,_PolyVInf;
1047 
1048       SPnt1.InfoFirst(Type,SegIndex1onP1,ParamOnLine);
1049       if(SegIndex1onP1 > thePoly1.NbSegments()) { SegIndex1onP1--; ParamOnLine = 1.0; }
1050       if(SegIndex1onP1 <= 0) { SegIndex1onP1=1; ParamOnLine = 0.0; }
1051       _PolyUInf = thePoly1.ApproxParamOnCurve(SegIndex1onP1,ParamOnLine);
1052       
1053       SPnt1.InfoSecond(Type,SegIndex1onP2,ParamOnLine);
1054       if(SegIndex1onP2 > thePoly2.NbSegments()) { SegIndex1onP2--; ParamOnLine = 1.0; }
1055       if(SegIndex1onP2 <= 0) { SegIndex1onP2=1; ParamOnLine = 0.0; }
1056       _PolyVInf = thePoly2.ApproxParamOnCurve(SegIndex1onP2,ParamOnLine);
1057       
1058       //----------------------------------------------------------------------
1059 
1060       if(ParamInfOnCurve1 > _PolyUInf) ParamInfOnCurve1=_PolyUInf;
1061       if(ParamInfOnCurve2 > _PolyVInf) ParamInfOnCurve2=_PolyVInf;
1062 
1063       if(ParamSupOnCurve1 < _PolyUInf) ParamSupOnCurve1=_PolyUInf;
1064       if(ParamSupOnCurve2 < _PolyVInf) ParamSupOnCurve2=_PolyVInf;
1065     }
1066 
1067     PolyUInf= ParamInfOnCurve1;
1068     PolyUSup= ParamSupOnCurve1;
1069     PolyVInf= ParamInfOnCurve2;
1070     PolyVSup= ParamSupOnCurve2;
1071     
1072     TheCurveTool::D0(C1,PolyUInf,P1);
1073     TheCurveTool::D0(C2,PolyVInf,P2);
1074     Standard_Real distmemesens = P1.SquareDistance(P2);
1075     TheCurveTool::D0(C2,PolyVSup,P2);
1076     Standard_Real distdiffsens = P1.SquareDistance(P2);
1077     if(distmemesens > distdiffsens) { 
1078       Standard_Real qwerty=PolyVInf; PolyVInf=PolyVSup; PolyVSup=qwerty;
1079     }
1080 
1081     if(  (  (thePoly1.DeflectionOverEstimation() > TolConf)
1082             ||(thePoly2.DeflectionOverEstimation() > TolConf))
1083             &&(NbIter<NBITER_MAX_POLYGON)) {
1084       
1085       IntRes2d_Domain RecursD1( TheCurveTool::Value(C1,ParamInfOnCurve1)
1086                                ,ParamInfOnCurve1,TolConf
1087                                ,TheCurveTool::Value(C1,ParamSupOnCurve1)
1088                                ,ParamSupOnCurve1,TolConf);
1089       IntRes2d_Domain RecursD2( TheCurveTool::Value(C2,ParamInfOnCurve2)
1090                                ,ParamInfOnCurve2,TolConf
1091                                ,TheCurveTool::Value(C2,ParamSupOnCurve2)
1092                                ,ParamSupOnCurve2,TolConf);
1093       //-- thePoly1(2) are not deleted,
1094       //-- finally they are destroyed. 
1095       //-- !! No untimely return !!
1096       Perform(C1,RecursD1,C2,RecursD2,Tol,TolConf,NbIter+1,DeltaU,DeltaV);
1097     }
1098     else { 
1099       //-----------------------------------------------------------------
1100       //-- Calculate Positions of Points on the curve and  
1101       //-- Transitions on each limit of the segment
1102       
1103       IntRes2d_Position Pos1 = IntRes2d_Middle;
1104       IntRes2d_Position Pos2 = IntRes2d_Middle;
1105       IntRes2d_Transition  Trans1,Trans2;
1106       
1107       TheCurveTool::D1(C1,PolyUInf,P1,Tan1);
1108       TheCurveTool::D1(C2,PolyVInf,P2,Tan2);
1109       
1110       if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    { 
1111               Pos1 = IntRes2d_Head;
1112       }
1113       else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { 
1114               Pos1 = IntRes2d_End;  
1115       }
1116       if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    { 
1117               Pos2 = IntRes2d_Head; 
1118       }
1119       else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { 
1120               Pos2 = IntRes2d_End;  
1121       }
1122 
1123       if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { 
1124               PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1125       }
1126       else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { 
1127               PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1128       }
1129       else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { 
1130               PolyVInf=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1131       }
1132       else { 
1133               PolyUInf=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1134       }
1135       
1136 
1137 
1138       if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf) 
1139                == Standard_False)
1140       {
1141               TheCurveTool::D2(C1,PolyUInf,P1,Tan1,Norm1);
1142               TheCurveTool::D2(C2,PolyVInf,P2,Tan2,Norm2);
1143               IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
1144                                                 Pos2,Tan2,Norm2,Trans2,TolConf);
1145       }
1146       IntRes2d_IntersectionPoint PtSeg1(P1,PolyUInf,PolyVInf
1147                                         ,Trans1,Trans2,Standard_False);
1148       //----------------------------------------------------------------------
1149       
1150       if((Abs(PolyUInf-PolyUSup) <= TheCurveTool::EpsX(C1)) 
1151               || (Abs(PolyVInf-PolyVSup) <= TheCurveTool::EpsX(C2)))
1152       { 
1153               Insert(PtSeg1);
1154       }
1155       else 
1156       { 
1157               TheCurveTool::D1(C1,PolyUSup,P1,Tan1);
1158               TheCurveTool::D1(C2,PolyVSup,P2,Tan2);
1159               Pos1 = IntRes2d_Middle; Pos2 = IntRes2d_Middle;
1160           
1161               if(P1.Distance(DomainOnCurve1.FirstPoint())<=DomainOnCurve1.FirstTolerance())    { 
1162                 Pos1 = IntRes2d_Head; 
1163               }
1164               else if(P1.Distance(DomainOnCurve1.LastPoint())<=DomainOnCurve1.LastTolerance()) { 
1165                 Pos1 = IntRes2d_End;  
1166               }
1167               if(P2.Distance(DomainOnCurve2.FirstPoint())<=DomainOnCurve2.FirstTolerance())    { 
1168                 Pos2 = IntRes2d_Head; 
1169               }
1170               else if(P2.Distance(DomainOnCurve2.LastPoint())<=DomainOnCurve2.LastTolerance()) { 
1171                 Pos2 = IntRes2d_End;  
1172               }
1173 
1174 
1175               if(Pos1==IntRes2d_Middle && Pos2!=IntRes2d_Middle) { 
1176                 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1177               }
1178               else if(Pos1!=IntRes2d_Middle && Pos2==IntRes2d_Middle) { 
1179                 PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1180               }
1181               else if(Abs(ParamInfOnCurve1-ParamSupOnCurve1) > Abs(ParamInfOnCurve2-ParamSupOnCurve2)) { 
1182                 PolyVSup=TheProjPCur::FindParameter( C2,P1,D2.FirstParameter(),D2.LastParameter(),TheCurveTool::EpsX(C2));
1183               }
1184               else { 
1185                 PolyUSup=TheProjPCur::FindParameter( C1,P2,D1.FirstParameter(),D1.LastParameter(),TheCurveTool::EpsX(C1));
1186               }
1187         
1188         if(IntImpParGen::DetermineTransition( Pos1,Tan1,Trans1,Pos2,Tan2,Trans2,TolConf)
1189            ==Standard_False) { 
1190           TheCurveTool::D2(C1,PolyUSup,P1,Tan1,Norm1);
1191           TheCurveTool::D2(C2,PolyVSup,P2,Tan2,Norm2);
1192           IntImpParGen::DetermineTransition(Pos1,Tan1,Norm1,Trans1,
1193                                             Pos2,Tan2,Norm2,Trans2,TolConf);
1194         }
1195         IntRes2d_IntersectionPoint PtSeg2(P1,PolyUSup,PolyVSup
1196                                           ,Trans1,Trans2,Standard_False);
1197         
1198               Standard_Boolean Oppos = (Tan1.Dot(Tan2) > 0.0)? Standard_False : Standard_True;
1199               if(ParamInfOnCurve1 > ParamSupOnCurve1) {
1200                 IntRes2d_IntersectionSegment Seg(PtSeg2,PtSeg1,Oppos,Standard_False);
1201                 Append(Seg);
1202               }
1203               else { 
1204                 IntRes2d_IntersectionSegment Seg(PtSeg1,PtSeg2,Oppos,Standard_False);
1205                 Append(Seg);
1206               }
1207       }
1208     }
1209   }
1210  return Standard_True;
1211 }
1212 
1213 //======================================================================
1214 //  GetIntersection
1215 //======================================================================
1216 
1217 void GetIntersection(const TheCurve& theC1, const Standard_Real theT1f, const Standard_Real theT1l,
1218                      const TheCurve& theC2, const Standard_Real theT2f, const Standard_Real theT2l, 
1219                      const Standard_Real theTolConf,
1220                      const Standard_Integer theMaxCount,
1221                      IntRes2d_IntersectionPoint& thePInt, Standard_Real& theDist,
1222                      Standard_Integer& theCount)
1223 {
1224   theCount++;
1225   //
1226   Standard_Real aTol2 = theTolConf*theTolConf;
1227   Standard_Real aPTol1 = Max(100.*Epsilon(Max(Abs(theT1f), Abs(theT1l))), Precision::PConfusion());
1228   Standard_Real aPTol2 = Max(100.*Epsilon(Max(Abs(theT2f), Abs(theT2l))), Precision::PConfusion());
1229   gp_Pnt2d aP1f, aP1l, aP2f, aP2l;
1230   Bnd_Box2d aB1, aB2;
1231   //
1232   TheCurveTool::D0(theC1, theT1f, aP1f);
1233   TheCurveTool::D0(theC1, theT1l, aP1l);
1234   aB1.Add(aP1f);
1235   aB1.Add(aP1l);
1236   aB1.Enlarge(theTolConf);
1237   //
1238   TheCurveTool::D0(theC2, theT2f, aP2f);
1239   TheCurveTool::D0(theC2, theT2l, aP2l);
1240   aB2.Add(aP2f);
1241   aB2.Add(aP2l);
1242   aB2.Enlarge(theTolConf);
1243   //
1244   if(aB1.IsOut(aB2))
1245   {
1246     theCount--;
1247     return;
1248   }
1249   //
1250   Standard_Boolean isSmall1 = (theT1l - theT1f) <= aPTol1 || aP1f.SquareDistance(aP1l) / 4. <= aTol2;
1251   Standard_Boolean isSmall2 = (theT2l - theT2f) <= aPTol2 || aP2f.SquareDistance(aP2l) / 4. <= aTol2;
1252 
1253   if((isSmall1 && isSmall2) || (theCount > theMaxCount))
1254   {
1255     //Seems to be intersection
1256     //Simple treatment of segment intersection
1257     gp_XY aPnts1[3] = {aP1f.XY(), (aP1f.XY() + aP1l.XY()) / 2., aP1l.XY()};
1258     gp_XY aPnts2[3] = {aP2f.XY(), (aP2f.XY() + aP2l.XY()) / 2., aP2l.XY()};
1259     Standard_Integer i, j, imin = -1, jmin = -1;
1260     Standard_Real dmin = RealLast(), d;
1261     for(i = 0; i < 3; i++)
1262     {
1263       for(j = 0; j < 3; j++)
1264       {
1265         d = (aPnts1[i] - aPnts2[j]).SquareModulus();
1266         if(d < dmin)
1267         {
1268           dmin=d;
1269           imin = i;
1270           jmin = j;
1271         }
1272       }
1273     }
1274     //
1275     dmin = Sqrt(dmin);
1276     if(theDist > dmin)
1277     {
1278       theDist = dmin;
1279       //
1280       Standard_Real t1;
1281       if(imin == 0)
1282       {
1283         t1 = theT1f;
1284       }
1285       else if(imin == 1)
1286       {
1287         t1 = (theT1f + theT1l) / 2.;
1288       }
1289       else
1290       {
1291         t1 = theT1l;
1292       }
1293       //
1294       Standard_Real t2;
1295       if(jmin == 0)
1296       {
1297         t2 = theT2f;
1298       }
1299       else if(jmin == 1)
1300       {
1301         t2 = (theT2f + theT2l) / 2.;
1302       }
1303       else
1304       {
1305         t2 = theT2l;
1306       }
1307       //
1308       gp_Pnt2d aPint((aPnts1[imin] + aPnts2[jmin])/2.);
1309       //
1310       IntRes2d_Transition aTrans1, aTrans2;
1311       thePInt.SetValues(aPint, t1, t2, aTrans1, aTrans2, Standard_False);
1312     }
1313     theCount--;
1314     return;
1315   }
1316 
1317   if(isSmall1)
1318   {
1319     Standard_Real aT2m = (theT2l + theT2f) / 2.;
1320     GetIntersection(theC1, theT1f, theT1l, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount);
1321     GetIntersection(theC1, theT1f, theT1l, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1322   }
1323   else if(isSmall2)
1324   {
1325     Standard_Real aT1m = (theT1l + theT1f) / 2.;
1326     GetIntersection(theC1, theT1f, aT1m, theC2, theT2f, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1327     GetIntersection(theC1, aT1m, theT1l, theC2, theT2f, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1328   }
1329   else
1330   {
1331     Standard_Real aT1m = (theT1l + theT1f) / 2.;
1332     Standard_Real aT2m = (theT2l + theT2f) / 2.;
1333     GetIntersection(theC1, theT1f, aT1m, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount);
1334     GetIntersection(theC1, theT1f, aT1m, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1335     GetIntersection(theC1, aT1m, theT1l, theC2, theT2f, aT2m, theTolConf, theMaxCount, thePInt, theDist, theCount);
1336     GetIntersection(theC1, aT1m, theT1l, theC2, aT2m, theT2l, theTolConf, theMaxCount, thePInt, theDist, theCount);
1337   }
1338 
1339 }
1340 
1341 //=======================================================================
1342 //function : GetMinNbPoints
1343 //purpose  : 
1344 //=======================================================================
1345 Standard_Integer IntCurve_IntPolyPolyGen::GetMinNbSamples() const
1346 {
1347   return myMinPntNb;
1348 }
1349 
1350 //=======================================================================
1351 //function : SetMinNbPoints
1352 //purpose  : 
1353 //=======================================================================
1354 void IntCurve_IntPolyPolyGen::SetMinNbSamples(const Standard_Integer theMinNbSamples)
1355 {
1356   myMinPntNb = theMinNbSamples;
1357 }