Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Created on: 1992-05-07
0002 // Created by: Jacques GOUSSARD
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 - Thu Jan 15 15:57:15 2004 OCC4455
0018 
0019 #include <IntPatch_ThePathPointOfTheSOnBounds.hxx>
0020 #include <IntPatch_TheSegmentOfTheSOnBounds.hxx>
0021 #include <IntPatch_RLine.hxx>
0022 #include <IntSurf.hxx>
0023 #include <TColStd_Array1OfInteger.hxx>
0024 #include <TColStd_SequenceOfReal.hxx>
0025 #include <IntPatch_GLine.hxx>
0026 #include <Extrema_ExtPC.hxx>
0027 #include <GeomAdaptor_Curve.hxx>
0028 #include <Geom_Ellipse.hxx>
0029 #include <Geom_Parabola.hxx>
0030 #include <Geom_Hyperbola.hxx>
0031 #include <IntPatch_ALine.hxx>
0032 
0033 
0034 static void PutPointsOnLine(const Handle(Adaptor3d_Surface)& S1,
0035                             const Handle(Adaptor3d_Surface)& S2,
0036                             const IntPatch_SequenceOfPathPointOfTheSOnBounds&,
0037                             const IntPatch_SequenceOfLine&,
0038                             const Standard_Boolean,
0039                             const Handle(Adaptor3d_TopolTool)&,
0040                             const IntSurf_Quadric&,
0041                             const IntSurf_Quadric&,
0042                             const Standard_Boolean,
0043                             const Standard_Real);
0044 
0045 static Standard_Boolean MultiplePoint(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0046                                       const Handle(Adaptor3d_TopolTool)& Domain,
0047                                       const IntSurf_Quadric& QuadSurf,
0048                                       const gp_Vec&    Normale,
0049                                       const IntPatch_SequenceOfLine& slin,
0050                                       TColStd_Array1OfInteger& Done,
0051                                       TColStd_Array1OfInteger& UsedLine,
0052                                       const Standard_Integer Index,
0053                                       const Standard_Boolean OnFirst,
0054                                       const Standard_Real theToler);
0055 
0056 static Standard_Boolean PointOnSecondDom(const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0057                                          const Handle(Adaptor3d_TopolTool)& Domain,
0058                                          const IntSurf_Quadric& QuadSurf,
0059                                          const gp_Vec&    Normale,
0060                                          const gp_Vec&    Vtgint,
0061                                          const Handle(IntPatch_Line)& lin,
0062                                          TColStd_Array1OfInteger& Done,
0063                                          const Standard_Integer Index,
0064                                          const Standard_Real theToler);
0065 
0066 static Standard_Boolean SingleLine (const gp_Pnt&,
0067                                     const Handle(IntPatch_Line)&,
0068                                     const Standard_Real,
0069                                     Standard_Real&,
0070                                     gp_Vec&);
0071 
0072 
0073 static Standard_Boolean FindLine(gp_Pnt& Psurf,
0074                                  const IntPatch_SequenceOfLine& slin,
0075                                  const Standard_Real Tol,
0076                                  TColStd_ListOfReal& theLParams,
0077                                  gp_Vec& Vtgtint,
0078                                  Standard_Integer& theLineIdx,
0079                                  Standard_Integer OnlyThisLine,
0080                                  const Handle(Adaptor2d_Curve2d)& thearc,
0081                                  Standard_Real& theparameteronarc,
0082                                  gp_Pnt& thepointonarc,
0083                                  const IntSurf_Quadric& QuadSurf1,
0084                                  const IntSurf_Quadric& QuadSurf2,
0085                                  Standard_Real& theOutputToler);
0086 
0087 static void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds&,
0088                              IntPatch_SequenceOfLine&,
0089                              const IntSurf_Quadric&,
0090                              const IntSurf_Quadric&,
0091                              const Standard_Boolean,
0092                              const Standard_Real);
0093 
0094 static void ProcessRLine (IntPatch_SequenceOfLine&,
0095                           const IntSurf_Quadric&,
0096                           const IntSurf_Quadric&,
0097                           const Standard_Real,
0098                           const Standard_Boolean theIsReqToKeepRLine);
0099 
0100 //-- le calcul de dist est completement faux ds la routine ci dessous a revoir (lbr le 18 nov 97)
0101 Standard_Boolean IntersectionWithAnArc(gp_Pnt& PSurf,
0102                                        const Handle(IntPatch_ALine)& alin,
0103                                        Standard_Real& para,
0104                                        const Handle(Adaptor2d_Curve2d)& thearc,
0105                                        Standard_Real& _theparameteronarc,
0106                                        gp_Pnt& thepointonarc,
0107                                        const IntSurf_Quadric& QuadSurf,
0108                                        const Standard_Real u0alin,
0109                                        const Standard_Real u1alin) { 
0110   Standard_Real dtheta,theta;
0111 #ifdef OCCT_DEBUG
0112   //Standard_Real u,v,A,B,C,cost,sint,sign;
0113 #endif
0114   //-- recherche bete du point le plus proche de thearc->Value(...)
0115   dtheta = (u1alin-u0alin)*0.01;
0116   Standard_Real du=0.000000001;
0117   if (du >= dtheta)
0118     du = dtheta/2;
0119   Standard_Real distmin = RealLast();
0120 
0121   Standard_Real thetamin = 0.;
0122 
0123   Standard_Real theparameteronarc = _theparameteronarc;
0124   for(Standard_Real _theta=u0alin+dtheta; _theta<=u1alin-dtheta; _theta+=dtheta) { 
0125     gp_Pnt P=alin->Value(_theta);
0126     Standard_Real d=P.Distance(PSurf);
0127     if(d<distmin) { 
0128       thetamin=_theta;
0129       distmin=d;
0130     }
0131   }
0132 
0133   Standard_Real bestpara =0., besttheta =0., bestdist =0., distinit =0. ;
0134 
0135   //-- Distance initiale
0136   {
0137     gp_Pnt pp0 = alin->Value(thetamin);
0138     Standard_Real ua0,va0;
0139     QuadSurf.Parameters(pp0,ua0,va0);
0140     gp_Pnt2d p2d;
0141     gp_Vec2d d2d;
0142     thearc->D1(theparameteronarc,p2d,d2d);
0143     gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
0144     distinit=PaPr.Magnitude();
0145   }
0146   theta = thetamin;
0147   //-- recherche a partir de theta et theparameteronarc
0148   Standard_Boolean cpasok=Standard_True;
0149   Standard_Integer nbiter=0;
0150   Standard_Real drmax = (thearc->LastParameter() - thearc->FirstParameter())*0.05;
0151   Standard_Real damax = (u1alin-u0alin)*0.05;
0152 
0153 
0154   
0155   bestdist = RealLast();
0156 
0157   do { 
0158     Standard_Real ua0,va0,ua1,va1;
0159     //-- alin->Curve().InternalUVValue(theta,ua0,va0,A,B,C,cost,sint,sign);
0160     //-- alin->Curve().InternalUVValue(theta+du,ua1,va1,A,B,C,cost,sint,sign);
0161     gp_Pnt pp0 = alin->Value(theta);
0162     gp_Pnt pp1 = alin->Value(theta+du);
0163     QuadSurf.Parameters(pp0,ua0,va0);
0164     QuadSurf.Parameters(pp1,ua1,va1);
0165     
0166     
0167     gp_Vec2d D1a((ua1-ua0)/du,(va1-va0)/du);
0168     gp_Pnt2d p2d;
0169     gp_Vec2d d2d;
0170     thearc->D1(theparameteronarc,p2d,d2d);
0171     gp_Vec2d PaPr(gp_Pnt2d(ua0,va0),p2d);
0172     
0173     Standard_Real pbd=PaPr.Magnitude();
0174     if(bestdist>pbd) {
0175       bestdist = pbd;
0176       bestpara = theparameteronarc;
0177       besttheta = theta;
0178     }
0179 
0180     D1a.SetCoord(-D1a.X(),-D1a.Y());
0181     
0182     Standard_Real d  = D1a.X()    *   d2d.Y()   -   D1a.Y()     * d2d.X();
0183     
0184     Standard_Real da = (-PaPr.X())*   d2d.Y()   -   (-PaPr.Y()) * d2d.X();
0185     Standard_Real dr =  D1a.X()   * (-PaPr.Y()) -   D1a.Y()     * (-PaPr.X());
0186     if(Abs(d)>1e-15) { 
0187       da/=d;
0188       dr/=d;
0189     }
0190     else { 
0191       if(Abs(PaPr.X())>Abs(PaPr.Y())) { 
0192         Standard_Real xx=PaPr.X();
0193         xx*=0.5;
0194         if(D1a.X()) { 
0195           da = -xx/D1a.X();
0196         }
0197         if(d2d.X()) { 
0198           dr = -xx/d2d.X();
0199         }
0200       }
0201       else { 
0202         Standard_Real yy=PaPr.Y();
0203         yy*=0.5;
0204         if(D1a.Y()) { 
0205           da = -yy/D1a.Y();
0206         }
0207         if(d2d.Y()) { 
0208           dr = -yy/d2d.Y();
0209         }       
0210       }
0211     } 
0212 //--     Standard_Real da = -PaPr.Dot(D1a);
0213 //--     Standard_Real dr = -PaPr.Dot(d2d);
0214     
0215     if(da<-damax) da=-damax;
0216     else if(da>damax) da=damax;
0217     if(dr<-drmax) dr=-drmax;
0218     else if(dr>drmax) dr=drmax;
0219 
0220     if(Abs(da)<1e-10 && Abs(dr)<1e-10) { 
0221       para = theta; 
0222       PSurf = alin->Value(para);
0223       _theparameteronarc=theparameteronarc;
0224       thepointonarc = alin->Value(para);
0225       cpasok=Standard_False;
0226 //--      printf("\nt:%d",nbiter);
0227       return(Standard_True);
0228     }
0229     else { 
0230       theta+=da;
0231       theparameteronarc+=dr;
0232       if(   theparameteronarc>thearc->LastParameter() ) { 
0233         theparameteronarc = thearc->LastParameter();
0234       }
0235       if(  theparameteronarc<thearc->FirstParameter() ) { 
0236         theparameteronarc = thearc->FirstParameter();
0237       }
0238       if( theta < u0alin) { 
0239         theta = u0alin;
0240       }
0241       if( theta > u1alin-du) { 
0242         theta = u1alin-du-du; 
0243       }
0244     }
0245     nbiter++;
0246   }
0247   while(cpasok && nbiter<20);
0248   if(bestdist < distinit) { 
0249     para = besttheta; 
0250     PSurf = alin->Value(para);
0251     _theparameteronarc=bestpara;
0252     thepointonarc = alin->Value(para);
0253 //--     printf("\nT:%d",nbiter);
0254     return(Standard_True);
0255   }
0256 //--   printf("\nF:%d",nbiter);
0257   return(Standard_False);
0258 }
0259 
0260 
0261 
0262 
0263 
0264 //-- ======================================================================
0265 static void Recadre(const Handle(Adaptor3d_Surface)& myHS1,
0266                     const Handle(Adaptor3d_Surface)& myHS2,
0267                     Standard_Real& u1,
0268                     Standard_Real& v1,
0269                     Standard_Real& u2,
0270                     Standard_Real& v2) { 
0271   Standard_Real f,l,lmf,fpls2;
0272   GeomAbs_SurfaceType typs1 = myHS1->GetType();
0273   GeomAbs_SurfaceType typs2 = myHS2->GetType();
0274 
0275   Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
0276   switch (typs1) { 
0277   case GeomAbs_Cylinder:
0278   case GeomAbs_Cone:
0279   case GeomAbs_Sphere: 
0280     { 
0281       myHS1IsUPeriodic = Standard_True;
0282       myHS1IsVPeriodic = Standard_False;
0283       break;
0284     }
0285   case GeomAbs_Torus:
0286     {
0287       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
0288       break;
0289     }
0290   default:
0291      {
0292        //-- Le cas de biparametrees periodiques est gere en amont
0293        myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
0294        break;
0295      }
0296   }
0297 
0298   Standard_Boolean myHS2IsUPeriodic,myHS2IsVPeriodic;
0299   switch (typs2) { 
0300   case GeomAbs_Cylinder:
0301   case GeomAbs_Cone:
0302   case GeomAbs_Sphere: 
0303     { 
0304       myHS2IsUPeriodic = Standard_True;
0305       myHS2IsVPeriodic = Standard_False;
0306       break;
0307     }
0308   case GeomAbs_Torus:
0309     {
0310       myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_True;
0311       break;
0312     }
0313   default:
0314      {
0315        //-- Le cas de biparametrees periodiques est gere en amont
0316        myHS2IsUPeriodic = myHS2IsVPeriodic = Standard_False;
0317        break;
0318      }
0319   }
0320   if(myHS1IsUPeriodic) {
0321     lmf = M_PI+M_PI; //-- myHS1->UPeriod();
0322     f = myHS1->FirstUParameter();
0323     l = myHS1->LastUParameter();
0324     fpls2=0.5*(f+l);
0325     while((u1 < f)&&((fpls2-u1) > (u1+lmf-fpls2)   )) { u1+=lmf; } 
0326     while((u1 > l)&&((u1-fpls2) > (fpls2-(u1-lmf)) )) { u1-=lmf; }
0327     
0328   }
0329   if(myHS1IsVPeriodic) {
0330     lmf = M_PI+M_PI; //-- myHS1->VPeriod(); 
0331     f = myHS1->FirstVParameter();
0332     l = myHS1->LastVParameter();
0333     fpls2=0.5*(f+l);
0334     while((v1 < f)&&((fpls2-v1) > (v1+lmf-fpls2)   )) { v1+=lmf; } 
0335     while((v1 > l)&&((v1-fpls2) > (fpls2-(v1-lmf)) )) { v1-=lmf; }
0336     //--    while(v1 < f) { v1+=lmf; } 
0337     //--    while(v1 > l) { v1-=lmf; }
0338   }
0339   if(myHS2IsUPeriodic) { 
0340     lmf = M_PI+M_PI; //-- myHS2->UPeriod();
0341     f = myHS2->FirstUParameter();
0342     l = myHS2->LastUParameter();
0343     fpls2=0.5*(f+l);
0344     while((u2 < f)&&((fpls2-u2) > (u2+lmf-fpls2)   )) { u2+=lmf; } 
0345     while((u2 > l)&&((u2-fpls2) > (fpls2-(u2-lmf)) )) { u2-=lmf; }
0346     //-- while(u2 < f) { u2+=lmf; } 
0347     //-- while(u2 > l) { u2-=lmf; }
0348   }
0349   if(myHS2IsVPeriodic) { 
0350     lmf = M_PI+M_PI; //-- myHS2->VPeriod();
0351     f = myHS2->FirstVParameter();
0352     l = myHS2->LastVParameter();
0353     fpls2=0.5*(f+l);
0354     while((v2 < f)&&((fpls2-v2) > (v2+lmf-fpls2)   )) { v2+=lmf; } 
0355     while((v2 > l)&&((v2-fpls2) > (fpls2-(v2-lmf)) )) { v2-=lmf; }
0356     //-- while(v2 < f) { v2+=lmf; } 
0357     //-- while(v2 > l) { v2-=lmf; }
0358   }
0359 }
0360 //=======================================================================
0361 //function : PutPointsOnLine
0362 //purpose  : 
0363 //=======================================================================
0364 void PutPointsOnLine(const Handle(Adaptor3d_Surface)& S1,
0365                      const Handle(Adaptor3d_Surface)& S2, 
0366                      const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0367                      const IntPatch_SequenceOfLine& slin,
0368                      const Standard_Boolean OnFirst,
0369                      const Handle(Adaptor3d_TopolTool)& Domain,
0370                      const IntSurf_Quadric& QuadSurf,
0371                      const IntSurf_Quadric& OtherQuad,
0372                      const Standard_Boolean multpoint,
0373                      const Standard_Real Tolarc) { 
0374   
0375   // Traitement des point (de listpnt) de depart. On les replace sur
0376   // la ligne d intersection, en leur affectant la transition correcte sur
0377   // cette ligne.
0378   Standard_Integer nbpnt = listpnt.Length();
0379   Standard_Integer nblin=slin.Length();
0380 
0381   if (!slin.Length() || !nbpnt) {
0382     return;
0383   }
0384   //
0385   Standard_Integer i,k;
0386   Standard_Integer linenumber;
0387   Standard_Real currentparameter,tolerance;
0388   Standard_Real U1,V1,U2,V2;
0389   Standard_Boolean goon;
0390   
0391   
0392   gp_Pnt Psurf, ptbid;
0393   gp_Vec Normale, Vtgint, Vtgrst;
0394   
0395   gp_Vec d1u,d1v;
0396   gp_Pnt2d p2d;
0397   gp_Vec2d d2d;
0398   
0399   IntSurf_Transition Transline,Transarc;
0400 
0401   Handle(Adaptor2d_Curve2d) currentarc;
0402   Handle(Adaptor3d_HVertex) vtx,vtxbis;
0403   
0404   IntPatch_Point solpnt;
0405   IntPatch_ThePathPointOfTheSOnBounds currentpointonrst;
0406   IntPatch_IType TheType;
0407 
0408   TColStd_Array1OfInteger UsedLine(1,nblin);
0409   TColStd_Array1OfInteger Done(1,nbpnt);
0410   for(i=1;i<=nbpnt;i++) Done(i) = 0; //-- Initialisation a la main 
0411   
0412   for (i=1; i<=nbpnt; i++) {
0413     
0414     if (Done(i) != 1) {
0415       currentpointonrst = listpnt.Value(i);
0416       Psurf   = currentpointonrst.Value();   // Point dans l espace
0417       tolerance = currentpointonrst.Tolerance();
0418       
0419       // On recherche d abord si on a correspondance avec un "point multiple"
0420       UsedLine.Init(0);
0421 
0422       goon = Standard_True;
0423       if (multpoint) {
0424 #if 1 
0425         Normale = QuadSurf.Normale(Psurf);     // Normale a la surface au point      
0426         currentarc = currentpointonrst.Arc();
0427         currentparameter = currentpointonrst.Parameter();
0428         currentarc->D1(currentparameter,p2d,d2d);
0429         QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
0430         Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0431 #endif      
0432         goon = MultiplePoint(listpnt,Domain,QuadSurf,Normale,slin,Done, UsedLine,
0433                              i, OnFirst, Tolarc);
0434       }
0435       if (goon) {
0436         Standard_Boolean linefound = Standard_False;
0437         
0438         for(Standard_Integer indiceline = 1; indiceline <=slin.Length(); indiceline++) { 
0439           if( UsedLine(indiceline) != 0 )
0440             continue;
0441           linenumber = indiceline;
0442 
0443           //-- Attention , les points peuvent etre deplaces 
0444           //-- il faut reprendre le point original
0445           currentpointonrst = listpnt.Value(i);
0446           currentarc = currentpointonrst.Arc();
0447           currentparameter = currentpointonrst.Parameter();
0448           Psurf   = currentpointonrst.Value();   // Point dans l espace
0449           tolerance = currentpointonrst.Tolerance();
0450           //-- 
0451 
0452 
0453           //  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 Begin
0454           if (! currentpointonrst.IsNew()) {
0455             Handle(Adaptor3d_HVertex) aVtx    = currentpointonrst.Vertex();
0456             Standard_Real aVtxTol = aVtx->Resolution(currentarc);
0457             Standard_Real aTolAng = 0.01*tolerance;
0458 
0459             tolerance = Max(tolerance, aVtxTol);
0460 
0461             gp_Vec aNorm1  = QuadSurf.Normale(Psurf);
0462             gp_Vec aNorm2  = OtherQuad.Normale(Psurf);
0463             //
0464             if (aNorm1.Magnitude()>gp::Resolution() &&
0465                 aNorm2.Magnitude()>gp::Resolution()) { 
0466             
0467               if (aNorm1.IsParallel(aNorm2, aTolAng))
0468                 tolerance = Sqrt(tolerance);
0469             }//
0470           }
0471           //  Modified by skv - Thu Jan 15 15:57:15 2004 OCC4455 End
0472           gp_Pnt pointonarc;
0473           Vtgint.SetCoord(0,0,0);
0474           Standard_Real aVertTol = Tolarc;
0475           TColStd_ListOfReal aLParams;
0476           linefound = FindLine(Psurf, slin, tolerance, aLParams, Vtgint, linenumber,
0477                                indiceline, currentarc, currentparameter,
0478                                pointonarc, QuadSurf, OtherQuad, aVertTol);
0479           if (linefound) {
0480             
0481 #if 1 
0482             Normale = QuadSurf.Normale(Psurf);     // Normale a la surface au point      
0483             currentarc = currentpointonrst.Arc();
0484             //-- currentparameter = currentpointonrst.Parameter();
0485             currentarc->D1(currentparameter,p2d,d2d);
0486             QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
0487             Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0488 #endif      
0489             
0490             
0491             
0492             const Handle(IntPatch_Line)& lin = slin.Value(linenumber);
0493             TheType = lin->ArcType();
0494             
0495             if (!OnFirst) { // on cherche la correspondance entre point sur domaine
0496               // de la premiere surface et point sur domaine de la
0497               // deuxieme surface
0498               
0499               goon = PointOnSecondDom (listpnt, Domain, QuadSurf, Normale, 
0500                                        Vtgint, lin, Done, i, aVertTol);
0501             }
0502             
0503             if (goon) {
0504               //-- Modification du 4 avril 97    tolerance->Tolarc
0505               //-- on replace sur le vertex la tolerance d entree et 
0506               //-- non la tolerance qui a servi au FindLine
0507               solpnt.SetValue(Psurf, aVertTol, Standard_False);
0508               
0509               U1 = p2d.X(); V1 = p2d.Y();
0510               OtherQuad.Parameters(Psurf,U2,V2);
0511               
0512               if (OnFirst) {
0513                 Recadre(S1,S2,U1,V1,U2,V2);
0514                 solpnt.SetParameters(U1,V1,U2,V2);
0515               }
0516               else {
0517                 Recadre(S1,S2,U2,V2,U1,V1);
0518                 solpnt.SetParameters(U2,V2,U1,V1);
0519               }
0520               
0521               if (! currentpointonrst.IsNew()) {
0522                 vtx = currentpointonrst.Vertex();
0523                 solpnt.SetVertex(OnFirst,vtx);
0524               }
0525               else {
0526                 //-- goon = Standard_False; ???? 
0527               }
0528               
0529               if(Normale.SquareMagnitude()<1e-16) { 
0530                 Transline.SetValue(Standard_True,IntSurf_Undecided);
0531                 Transarc.SetValue(Standard_True,IntSurf_Undecided);         
0532               }
0533               else {                            
0534                 IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
0535               }
0536               solpnt.SetArc(OnFirst,currentarc, currentparameter,
0537                             Transline,Transarc);
0538 
0539               for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
0540                    anItr.More(); anItr.Next())
0541               {
0542                 solpnt.SetParameter(anItr.Value());
0543                 if (TheType == IntPatch_Analytic)
0544                 {
0545                   Handle(IntPatch_ALine)::DownCast(lin)->AddVertex(solpnt);
0546                 }
0547                 else
0548                 {
0549                   Handle(IntPatch_GLine)::DownCast(lin)->AddVertex(solpnt);
0550                 }
0551               }
0552 
0553               Done(i) = 1;
0554               
0555               if (goon) {
0556                 for (k=i+1; k<= nbpnt; k++) {
0557                   if (Done(k) != 1) {
0558                     currentpointonrst = listpnt.Value(k);
0559                     if (!currentpointonrst.IsNew()) {
0560                       vtxbis = currentpointonrst.Vertex();
0561                       if(vtx.IsNull()) { 
0562                       }               
0563                       else if (Domain->Identical(vtx, vtxbis)) {
0564                         solpnt.SetVertex(OnFirst,vtxbis);
0565                         solpnt.SetTolerance(Tolarc);
0566                         currentarc = currentpointonrst.Arc();
0567                         currentparameter = currentpointonrst.Parameter();
0568                         
0569                         //                    currentarc->D1(currentparameter,ptbid,Vtgrst);
0570                         currentarc->D1(currentparameter,p2d,d2d);
0571                         Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0572                         if(Normale.SquareMagnitude()<1e-16) { 
0573                           Transline.SetValue(Standard_True,IntSurf_Undecided);
0574                           Transarc.SetValue(Standard_True,IntSurf_Undecided);       
0575                         }
0576                         else {                                    
0577                           IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
0578                                                   Transline,Transarc);
0579                         }
0580                         solpnt.SetArc(OnFirst,currentarc,currentparameter,
0581                                       Transline,Transarc);
0582                         if (TheType == IntPatch_Analytic) {
0583                           Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(solpnt);
0584                         }
0585                         else {
0586                           Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(solpnt);
0587                         }
0588                         Done(k) = 1;
0589                       }
0590                     }
0591                   }
0592                 }
0593               }
0594             }
0595           }
0596           else {
0597             Done(i) = 1; // il faudra tester si IsNew ou pas
0598             // et traiter en consequence
0599           }
0600         }
0601       }
0602     }
0603   }
0604 }
0605 
0606 
0607 Standard_Boolean  MultiplePoint (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0608                                  const Handle(Adaptor3d_TopolTool)& Domain,
0609                                  const IntSurf_Quadric& QuadSurf,
0610                                  const gp_Vec&    Normale,
0611                                  const IntPatch_SequenceOfLine& slin,
0612                                  TColStd_Array1OfInteger& Done,
0613                                  TColStd_Array1OfInteger& UsedLine,
0614                                  const Standard_Integer Index,
0615                                  const Standard_Boolean OnFirst,
0616                                  const Standard_Real theToler) {
0617 
0618 // Traitement des points "multiples".
0619 
0620   
0621   Standard_Integer k,ii,jj,nbvtx;
0622   Standard_Integer nblin = slin.Length();
0623   IntPatch_IType TheType;
0624   
0625   
0626   IntSurf_Transition Transline,Transarc;
0627 
0628 
0629   IntPatch_Point intpt;
0630   Handle(Adaptor2d_Curve2d) currentarc;
0631   Handle(Adaptor3d_HVertex) vtx,vtxbis;
0632 
0633   Standard_Integer nbpnt = listpnt.Length();
0634   IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
0635   IntPatch_ThePathPointOfTheSOnBounds otherpt;
0636   gp_Pnt Point = currentpointonrst.Value();
0637   TColStd_Array1OfInteger localdone(1,nbpnt); localdone.Init(0);
0638   for (ii=1; ii<=nbpnt; ii++) {
0639     localdone(ii)=Done(ii);
0640   }
0641 
0642   Standard_Real currentparameter;
0643   Standard_Real Paraint;
0644   gp_Vec Vtgint,Vtgrst;
0645   gp_Pnt ptbid;
0646 
0647   gp_Vec d1u,d1v;
0648   gp_Pnt2d p2d;
0649   gp_Vec2d d2d;
0650 
0651   Standard_Boolean goon;
0652 
0653   Standard_Boolean Retvalue = Standard_True;
0654 
0655   for (ii = 1; ii <= nblin; ii++) {
0656     const Handle(IntPatch_Line)& slinValueii = slin.Value(ii);
0657     TheType = slinValueii->ArcType();
0658     if (TheType == IntPatch_Analytic) {
0659       nbvtx = Handle(IntPatch_ALine)::DownCast (slinValueii)->NbVertex();
0660     }
0661     else {
0662       nbvtx = Handle(IntPatch_GLine)::DownCast (slinValueii)->NbVertex();
0663     }
0664     jj = 1;
0665     while (jj <= nbvtx) {
0666       if (TheType == IntPatch_Analytic) {
0667         intpt = Handle(IntPatch_ALine)::DownCast (slinValueii)->Vertex(jj);
0668       }
0669       else {
0670         intpt = Handle(IntPatch_GLine)::DownCast (slinValueii)->Vertex(jj);
0671       }
0672       if (intpt.IsMultiple() && 
0673           (( OnFirst && !intpt.IsOnDomS1()) ||
0674            (!OnFirst && !intpt.IsOnDomS2()))) {
0675         if (Point.Distance(intpt.Value()) <= intpt.Tolerance()) {
0676           Retvalue = Standard_False;
0677           Standard_Boolean foo = SingleLine(Point,slinValueii,
0678                                             intpt.Tolerance(),Paraint,Vtgint);
0679           if (!foo) {
0680             return Standard_False;   // ne doit pas se produire
0681           }
0682 
0683           if (!currentpointonrst.IsNew()) {
0684             goon = Standard_True;
0685             vtx = currentpointonrst.Vertex();
0686             intpt.SetVertex(OnFirst,vtx);
0687           } 
0688           else {
0689             goon = Standard_False;
0690           }
0691           currentarc = currentpointonrst.Arc();
0692           currentparameter = currentpointonrst.Parameter();
0693           currentarc->D1(currentparameter,p2d,d2d);
0694           QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
0695           Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0696 
0697           //-- Si la normale est nulle (apex d un cone) On simule une transition UNKNOWN
0698           if(Normale.SquareMagnitude()<1e-16) { 
0699             Transline.SetValue(Standard_True,IntSurf_Undecided);
0700             Transarc.SetValue(Standard_True,IntSurf_Undecided);     
0701           }
0702           else { 
0703             IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
0704           }
0705 
0706           //-- Avant, on ne mettait pas ce point (17 nov 97)
0707           //--printf("\n ImpImp_0  : Point(%g,%g,%g)  intpt(%g,%g,%g) \n",
0708           //--  Point.X(),Point.Y(),Point.Z(),intpt.Value().X(),intpt.Value().Y(),intpt.Value().Z());
0709           intpt.SetValue(Point);
0710 
0711           intpt.SetArc(OnFirst,currentarc,currentparameter,
0712                        Transline,Transarc);
0713           intpt.SetTolerance(theToler);
0714 
0715           if (TheType == IntPatch_Analytic) {
0716             Handle(IntPatch_ALine)::DownCast (slinValueii)->Replace(jj,intpt);
0717           }
0718           else {
0719             Handle(IntPatch_GLine)::DownCast (slinValueii)->Replace(jj,intpt);
0720           }
0721           localdone(Index) = 1;
0722           if (goon) {
0723             for (k=Index+1; k<= nbpnt; k++) {
0724               if (Done(k) != 1) {
0725                 otherpt= listpnt.Value(k);
0726                 if (!otherpt.IsNew()) {
0727                   vtxbis = otherpt.Vertex();
0728                   if (Domain->Identical(vtx, vtxbis)) {
0729                     intpt.SetVertex(OnFirst,vtxbis);
0730                     currentarc = otherpt.Arc();
0731                     currentparameter = otherpt.Parameter();
0732                     
0733                     currentarc->D1(currentparameter,p2d,d2d);
0734                     Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0735                     if(Normale.SquareMagnitude()<1e-16) { 
0736                       Transline.SetValue(Standard_True,IntSurf_Undecided);
0737                       Transarc.SetValue(Standard_True,IntSurf_Undecided);           
0738                     }
0739                     else {    
0740                       IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
0741                                               Transline,Transarc);
0742                     }
0743                     intpt.SetArc(OnFirst,currentarc,currentparameter,
0744                                  Transline,Transarc);
0745                     intpt.SetTolerance(theToler);
0746                     if (TheType == IntPatch_Analytic) {
0747                       Handle(IntPatch_ALine)::DownCast (slinValueii)->AddVertex(intpt);
0748                     }
0749                     else {
0750                       Handle(IntPatch_GLine)::DownCast (slinValueii)->AddVertex(intpt);
0751                     }
0752                     UsedLine(ii) = 1;
0753                     Retvalue = Standard_True;
0754                     localdone(k) = 1;
0755                   }
0756                 }
0757               }
0758             }
0759           }
0760 //--           jj = nbvtx +1;
0761         }
0762 //--         else {
0763           jj = jj+1;
0764 //--        }
0765       }
0766       else {
0767         jj = jj+1;
0768       }
0769     }
0770   }
0771   
0772   for (ii=1; ii<=nbpnt;ii++) {
0773     Done(ii) = localdone(ii);
0774   }
0775   
0776   return Retvalue;
0777 }
0778     
0779 
0780 
0781 Standard_Boolean PointOnSecondDom (const IntPatch_SequenceOfPathPointOfTheSOnBounds& listpnt,
0782                                    const Handle(Adaptor3d_TopolTool)& Domain,
0783                                    const IntSurf_Quadric& QuadSurf,
0784                                    const gp_Vec&    Normale,
0785                                    const gp_Vec&    Vtgint,
0786                                    const Handle(IntPatch_Line)& lin,
0787                                    TColStd_Array1OfInteger& Done,
0788                                    const Standard_Integer Index,
0789                                    const Standard_Real theToler)
0790      
0791 
0792 // Duplication des points sur domaine de l autre surface.
0793 // On sait que le vertex sous-jacent est PntRef
0794 
0795 
0796 {
0797 
0798   Standard_Integer k,jj,nbvtx;
0799   IntPatch_IType TheType;
0800 
0801   IntSurf_Transition Transline,Transarc;
0802   IntPatch_Point intpt;
0803   Handle(Adaptor2d_Curve2d) currentarc;
0804   Handle(Adaptor3d_HVertex) vtx,vtxbis;
0805   gp_Pnt ptbid;
0806   gp_Vec Vtgrst;
0807 
0808   gp_Vec d1u,d1v;
0809   gp_Pnt2d p2d;
0810   gp_Vec2d d2d;
0811 
0812   Standard_Integer nbpnt = listpnt.Length();
0813   IntPatch_ThePathPointOfTheSOnBounds currentpointonrst = listpnt.Value(Index);
0814   Standard_Real currentparameter;
0815 
0816   Standard_Boolean goon;
0817   Standard_Boolean Retvalue = Standard_True;
0818 
0819   TheType = lin->ArcType();
0820   if (TheType == IntPatch_Analytic) {
0821     nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
0822   }
0823   else {
0824     nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
0825   }
0826   jj = 1;
0827   while (jj <= nbvtx) {
0828     if (TheType == IntPatch_Analytic) {
0829       intpt = Handle(IntPatch_ALine)::DownCast (lin)->Vertex(jj);
0830     }
0831     else {
0832       intpt = Handle(IntPatch_GLine)::DownCast (lin)->Vertex(jj);
0833     }
0834     if (!intpt.IsOnDomS2()) {
0835       if (currentpointonrst.Value().Distance(intpt.Value()) <= 
0836           intpt.Tolerance()) {
0837         Retvalue = Standard_False;
0838         if (!currentpointonrst.IsNew()) {
0839           goon = Standard_True;
0840           vtx = currentpointonrst.Vertex();
0841           intpt.SetVertex(Standard_False,vtx);
0842         }
0843         else {
0844           goon = Standard_False;
0845         }
0846         currentarc = currentpointonrst.Arc();
0847         currentparameter = currentpointonrst.Parameter();
0848         currentarc->D1(currentparameter,p2d,d2d);
0849         QuadSurf.D1(p2d.X(),p2d.Y(),ptbid,d1u,d1v);
0850         Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0851         if(Normale.SquareMagnitude()<1e-16) { 
0852           Transline.SetValue(Standard_True,IntSurf_Undecided);
0853           Transarc.SetValue(Standard_True,IntSurf_Undecided);       
0854         }
0855         else {          
0856           IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,Transline,Transarc);
0857         }
0858         intpt.SetArc(Standard_False,currentarc,currentparameter,
0859                      Transline,Transarc);
0860         intpt.SetTolerance(theToler);
0861 
0862         if (TheType == IntPatch_Analytic) {
0863           Handle(IntPatch_ALine)::DownCast (lin)->Replace(jj,intpt);
0864         }
0865         else {
0866           Handle(IntPatch_GLine)::DownCast (lin)->Replace(jj,intpt);
0867         }
0868         Done(Index) = 1;
0869 
0870         if (goon) {
0871           for (k=Index+1; k<= nbpnt; k++) {
0872             if (Done(k) != 1) {
0873               currentpointonrst = listpnt.Value(k);
0874               if (!currentpointonrst.IsNew()) {
0875                 vtxbis = currentpointonrst.Vertex();
0876                   if (Domain->Identical(vtx, vtxbis)) {
0877                   intpt.SetVertex(Standard_False,vtxbis);
0878                   currentarc = currentpointonrst.Arc();
0879                   currentparameter = currentpointonrst.Parameter();
0880                   currentarc->D1(currentparameter,p2d,d2d);
0881                   Vtgrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
0882                   if(Normale.SquareMagnitude()<1e-16) { 
0883                     Transline.SetValue(Standard_True,IntSurf_Undecided);
0884                     Transarc.SetValue(Standard_True,IntSurf_Undecided);     
0885                   }
0886                   else {                                    
0887                     IntSurf::MakeTransition(Vtgint,Vtgrst,Normale,
0888                                             Transline,Transarc);
0889                   }
0890                   intpt.SetArc(Standard_False,currentarc,currentparameter,
0891                                Transline,Transarc);
0892                   intpt.SetTolerance(theToler);
0893                   if (TheType == IntPatch_Analytic) {
0894                     Handle(IntPatch_ALine)::DownCast (lin)->AddVertex(intpt);
0895                   }
0896                   else {
0897                     Handle(IntPatch_GLine)::DownCast (lin)->AddVertex(intpt);
0898                   }
0899                   Done(k) = 1;
0900                 }
0901               }
0902             }
0903           }
0904         }
0905         //-- jj = nbvtx + 1;
0906         jj++;
0907       }
0908       else {
0909         jj = jj+1;
0910       }
0911     }
0912     else {
0913       jj = jj+1;
0914     }
0915     if (TheType == IntPatch_Analytic) {
0916       nbvtx = Handle(IntPatch_ALine)::DownCast (lin)->NbVertex();
0917     }
0918     else {
0919       nbvtx = Handle(IntPatch_GLine)::DownCast (lin)->NbVertex();
0920     }
0921   }
0922   return Retvalue;
0923 }
0924 
0925 
0926 
0927 Standard_Boolean FindLine(gp_Pnt& Psurf,
0928                           const IntPatch_SequenceOfLine& slin,
0929                           const Standard_Real Tol,
0930                           TColStd_ListOfReal& theLParams,
0931                           gp_Vec& Vtgtint,
0932                           Standard_Integer& theLineIdx,
0933                           Standard_Integer OnlyThisLine,
0934                           const Handle(Adaptor2d_Curve2d)& thearc,
0935                           Standard_Real& theparameteronarc,
0936                           gp_Pnt& thepointonarc,
0937                           const IntSurf_Quadric& QuadSurf1,
0938                           const IntSurf_Quadric& QuadSurf2,
0939                           Standard_Real& theOutputToler)
0940 {
0941   if ((QuadSurf1.Distance(Psurf) > Tol) || (QuadSurf2.Distance(Psurf) > Tol))
0942     return Standard_False;
0943 
0944 // Traitement du point de depart ayant pour representation Psurf
0945 // dans l espace. On recherche la ligne d intersection contenant ce point.
0946 // On a en sortie la ligne, et le parametre et sa tangente du point sur
0947 // la ligne d intersection.
0948   const Standard_Real aSqTol = Tol*Tol;
0949   Standard_Real aSqDistMin = RealLast();
0950   Standard_Real aSqDist, para;
0951   Standard_Real lower,upper;
0952   gp_Pnt pt;
0953   Standard_Integer i;
0954   IntPatch_IType typarc;
0955 
0956   Standard_Real aParaInt = RealLast();
0957   Standard_Integer nblin = slin.Length();
0958   for (i=1; i<=nblin; i++) {
0959     if(OnlyThisLine) { i=OnlyThisLine; nblin=0; }
0960     const Handle(IntPatch_Line)& lin = slin.Value(i);
0961     typarc = lin->ArcType();
0962     if (typarc == IntPatch_Analytic) {
0963       Standard_Boolean foo;
0964       lower = Handle(IntPatch_ALine)::DownCast (lin)->FirstParameter(foo);
0965       upper = Handle(IntPatch_ALine)::DownCast (lin)->LastParameter(foo);
0966     }
0967     else {
0968       if (Handle(IntPatch_GLine)::DownCast (lin)->HasFirstPoint()) {
0969         lower = Handle(IntPatch_GLine)::DownCast (lin)->FirstPoint().ParameterOnLine();
0970       }
0971       else {
0972         lower = RealFirst();
0973       }
0974       if (Handle(IntPatch_GLine)::DownCast (lin)->HasLastPoint()) {
0975         upper = Handle(IntPatch_GLine)::DownCast (lin)->LastPoint().ParameterOnLine();
0976       }
0977       else {
0978         upper = RealLast();
0979       }
0980     }
0981 
0982     switch (typarc) {
0983     case IntPatch_Lin :
0984       {
0985         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
0986         if (para <= upper && para >= lower) {
0987           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Line());
0988           aSqDist = Psurf.SquareDistance(pt);
0989           if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
0990           {
0991             aSqDistMin = aSqDist;
0992             aParaInt = para;
0993             theLineIdx = i;
0994           }
0995         }
0996       }
0997       break;
0998     case IntPatch_Circle :
0999       {
1000         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
1001         if ((para <= upper && para >= lower) ||
1002             (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
1003             (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
1004           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Circle());
1005           aSqDist = Psurf.SquareDistance(pt);
1006           if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1007           {
1008             aSqDistMin = aSqDist;
1009             aParaInt = para;
1010             theLineIdx = i;
1011           }
1012         }
1013       }
1014       break;
1015     case IntPatch_Ellipse :
1016       {
1017         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
1018         if ((para <= upper && para >= lower) ||
1019             (para + 2.*M_PI <=upper && para + 2.*M_PI >= lower) ||
1020             (para - 2.*M_PI <=upper && para - 2.*M_PI >= lower)) {
1021           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse());
1022           aSqDist = Psurf.SquareDistance(pt);
1023           if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1024           {
1025             aSqDistMin = aSqDist;
1026             aParaInt = para;
1027             theLineIdx = i;
1028           }
1029         }
1030       }
1031       break;
1032     case IntPatch_Parabola :
1033       {
1034         
1035 #if 0   
1036         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
1037         if (para <= upper && para >= lower) {
1038           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Parabola());
1039           dist = Psurf.Distance(pt);
1040           if (dist< distmin) {
1041             distmin = dist;
1042             Paraint = para;
1043             Range = i;
1044           }
1045         }
1046 #else 
1047         //-- Le calcul du parametre sur une parabole est mal fait ds ElCLib. Il ne tient pas compte
1048         //-- de la meilleure facon de calculer (axe X ou axe Y). Bilan : Si la parabole est tres 
1049         //-- pointue (focal de l'ordre de 1e-2 et si le point est a un parametre grand, ca foire. )
1050         //-- On ne peut pas modifier faciolement ds ElCLib car on ne passe pas la focale. ...
1051         const gp_Parab& Parab=Handle(IntPatch_GLine)::DownCast (lin)->Parabola();
1052         para = ElCLib::Parameter(Parab,Psurf);
1053         if (para <= upper && para >= lower) {
1054           Standard_Integer amelioration=0;
1055           //-- cout<<"\n ****** \n";
1056           do { 
1057             Standard_Real parabis = para+0.0000001;
1058             
1059             pt = ElCLib::Value(para,Parab);
1060             aSqDist = Psurf.SquareDistance(pt);
1061             
1062             const gp_Pnt ptbis = ElCLib::Value(parabis,Parab);
1063             const Standard_Real distbis = Psurf.Distance(ptbis);
1064             const Standard_Real aDist = Sqrt(aSqDist);
1065             const Standard_Real ddist = distbis - aDist;
1066             
1067             //--cout<<" para: "<<para<<"    dist:"<<dist<<"   ddist:"<<ddist<<endl;
1068             
1069             if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1070             {
1071               aSqDistMin = aSqDist;
1072               aParaInt = para;
1073               theLineIdx = i;
1074             }
1075             if (aSqDist < Precision::SquarePConfusion())
1076             {
1077               amelioration = 100;
1078             }
1079               
1080             if(ddist>1.0e-9 || ddist<-1.0e-9 ) { 
1081               para = para - aDist*(parabis - para) / ddist;
1082             }
1083             else { 
1084               amelioration=100;
1085             }
1086           }
1087           while(++amelioration < 5);
1088         }
1089 
1090 
1091 #endif
1092       }
1093       break;
1094     case IntPatch_Hyperbola :
1095       {
1096         para = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
1097         if (para <= upper && para >= lower) {
1098           pt = ElCLib::Value(para,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola());
1099           aSqDist = Psurf.SquareDistance(pt);
1100           if ((aSqDist < aSqTol) && (aSqDist < aSqDistMin))
1101           {
1102             aSqDistMin = aSqDist;
1103             aParaInt = para;
1104             theLineIdx = i;
1105           }
1106         }
1107       }
1108       break;
1109 
1110     case IntPatch_Analytic :
1111       {
1112         Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
1113         TColStd_ListOfReal aLParams;
1114         alin->FindParameter(Psurf, aLParams);
1115         if (!aLParams.IsEmpty())
1116         {
1117           // All found distances are already in some internal tolerance
1118           // set in alin->FindParameter(...) method.
1119 
1120           aSqDist = RealLast();
1121           for (TColStd_ListIteratorOfListOfReal anItr(aLParams);
1122                anItr.More(); anItr.Next())
1123           {
1124             pt = alin->Value(anItr.Value());
1125             const Standard_Real aSqD = Psurf.SquareDistance(pt);
1126             if (aSqD < aSqDist)
1127             {
1128               aSqDist = aSqD;
1129             }
1130           }
1131 
1132           if (aSqDist < aSqDistMin)
1133           {
1134             aSqDistMin = aSqDist;
1135             theLParams = aLParams;
1136             theLineIdx = i;
1137           }
1138         }
1139         else { 
1140           //-- le point n a pas ete trouve par bete projection.
1141           //-- on essaie l intersection avec la restriction en 2d
1142           Standard_Real theparamonarc = theparameteronarc;
1143 //#ifdef OCCT_DEBUG
1144 //        Standard_Real anpara=para;
1145 //#endif
1146           gp_Pnt CopiePsurf=Psurf;
1147           Standard_Boolean IntersectIsOk = IntersectionWithAnArc(CopiePsurf, alin, para, 
1148                                                                  thearc, theparamonarc,
1149                                                                  thepointonarc,
1150                                                                  QuadSurf1,
1151                                                                  lower, upper);
1152           aSqDist = CopiePsurf.SquareDistance(Psurf);
1153           if(IntersectIsOk) {
1154             if (aSqDist < aSqTol)
1155             {
1156               theparameteronarc = theparamonarc;
1157               Psurf = thepointonarc;
1158               aSqDistMin = aSqDist;
1159               theLParams.Append(para);
1160               theLineIdx = i;
1161             }
1162           }
1163         }
1164       }
1165       break;
1166 
1167     case IntPatch_Walking: // impossible . c est pour eviter les warnings
1168       {
1169       }
1170     case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1171       {
1172       }
1173     }
1174   }
1175 
1176   if (aSqDistMin == RealLast())
1177     return Standard_False;
1178 
1179   theOutputToler = Max(theOutputToler, Sqrt(aSqDistMin));
1180 
1181   typarc = slin.Value(theLineIdx)->ArcType();
1182 
1183   // Computation of tangent vector
1184   switch (typarc) {
1185   case IntPatch_Lin :
1186     theLParams.Append(aParaInt);
1187     Vtgtint = (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Line().Direction();
1188     break;
1189   case IntPatch_Circle :
1190     theLParams.Append(aParaInt);
1191     Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Circle(), 1);
1192     break;
1193   case IntPatch_Ellipse :
1194     theLParams.Append(aParaInt);
1195     Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Ellipse(), 1);
1196     break;
1197   case IntPatch_Parabola :
1198     theLParams.Append(aParaInt);
1199     Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Parabola(), 1);
1200     break;
1201   case IntPatch_Hyperbola :
1202     theLParams.Append(aParaInt);
1203     Vtgtint = ElCLib::DN(aParaInt, (*((Handle(IntPatch_GLine)*)&slin(theLineIdx)))->Hyperbola(), 1);
1204     break;
1205 
1206   case IntPatch_Analytic:
1207     {
1208       if (!Handle(IntPatch_ALine)::DownCast(slin(theLineIdx))->D1(theLParams.Last(), pt, Vtgtint))
1209       {
1210         //Previously (before the fix #29807) this code tried to process case
1211         //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
1212         //computed Vtgtint input argument value. Currently, any singularities
1213         //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
1214         //Therefore this code has been deleted as deprecated.
1215 
1216         Vtgtint.SetCoord(0.0, 0.0, 0.0);
1217       }
1218     }
1219     break;
1220   case IntPatch_Walking: // impossible . c est pour eviter les warnings
1221     {
1222     }
1223   case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1224     {
1225     }
1226     
1227   }
1228   return Standard_True;
1229 }
1230 
1231 //=======================================================================
1232 //function : SingleLine
1233 //purpose  : Traitement du point de depart ayant pour representation Psurf
1234 //            dans l espace. On le replace sur la ligne d intersection; On a en sortie
1235 //            son parametre et sa tangente sur la ligne d intersection.
1236 //            La fonction renvoie False si le point projete est a une distance
1237 //            superieure a Tol du point a projeter.
1238 //=======================================================================
1239 Standard_Boolean  SingleLine(const gp_Pnt& Psurf,
1240                              const Handle(IntPatch_Line)& lin,
1241                              const Standard_Real Tol,
1242                              Standard_Real& Paraint,
1243                              gp_Vec& Vtgtint)
1244 {
1245   IntPatch_IType typarc = lin->ArcType();
1246 
1247   Standard_Real parproj = 0.;
1248   gp_Vec tgint;
1249   gp_Pnt ptproj;
1250   Standard_Boolean retvalue;
1251 
1252   switch (typarc) {
1253   case IntPatch_Lin :
1254     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Line(),Psurf);
1255     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Line(),ptproj,tgint);
1256     break;
1257   case IntPatch_Circle :
1258     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Circle(),Psurf);
1259     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Circle(),ptproj,tgint);
1260     break;
1261   case IntPatch_Ellipse :
1262     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),Psurf);
1263     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Ellipse(),ptproj,tgint);
1264     break;
1265   case IntPatch_Parabola :
1266     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),Psurf);
1267     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Parabola(),ptproj,tgint);
1268     break;
1269   case IntPatch_Hyperbola :
1270     parproj = ElCLib::Parameter(Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),Psurf);
1271     ElCLib::D1(parproj,Handle(IntPatch_GLine)::DownCast (lin)->Hyperbola(),ptproj,tgint);
1272     break;
1273   case IntPatch_Analytic :
1274     {
1275       Handle(IntPatch_ALine) alin(Handle(IntPatch_ALine)::DownCast(lin));
1276       TColStd_ListOfReal aLParams;
1277       alin->FindParameter(Psurf, aLParams);
1278       if (!aLParams.IsEmpty())
1279       {
1280         ptproj = Psurf;
1281         parproj = aLParams.Last();
1282         gp_Pnt aPtemp;
1283         if (!alin->D1(parproj, aPtemp, tgint))
1284         {
1285           //Previously (before the fix #29807) this code tried to process case
1286           //when Handle(IntPatch_ALine)::D1(...) method returns FALSE and
1287           //computed Vtgtint input argument value. Currently, any singularities
1288           //must be processed by high-level algorithms (IntPatch_SpecialPoints class).
1289           //Therefore this code has been deleted as deprecated.
1290 
1291           tgint.SetCoord(0.0, 0.0, 0.0);
1292         }
1293       }
1294       else
1295       {
1296         //-- cout << "---- Pb sur ligne analytique dans SingleLine" << endl;
1297         //-- cout << "     Find Parameter"<<endl;
1298         return Standard_False;
1299       }
1300     }
1301     break;
1302   case IntPatch_Walking: // impossible . c est pour eviter les warnings
1303     {
1304     }
1305   case IntPatch_Restriction: // impossible . c est pour eviter les warnings
1306     {
1307     }
1308   }
1309 
1310   if (Psurf.Distance(ptproj) <= Tol) {
1311     Paraint = parproj;
1312     Vtgtint = tgint;
1313     retvalue = Standard_True;
1314   }
1315   else {
1316     retvalue = Standard_False;
1317   }
1318   return retvalue;
1319 }
1320 
1321 
1322 void ProcessSegments (const IntPatch_SequenceOfSegmentOfTheSOnBounds& listedg,
1323                       IntPatch_SequenceOfLine& slin,
1324                       const IntSurf_Quadric& Quad1,
1325                       const IntSurf_Quadric& Quad2,
1326                       const Standard_Boolean OnFirst,
1327                       const Standard_Real TolArc) {
1328      
1329   Standard_Integer i,j,k;
1330   Standard_Integer nbedg = listedg.Length();
1331   Standard_Integer Nblines,Nbpts;
1332 
1333   Handle(Adaptor2d_Curve2d) arcRef;
1334   IntPatch_Point ptvtx, newptvtx;
1335 
1336   Handle(IntPatch_RLine)  rline; //-- On fait rline = new ... par la suite 
1337 
1338   IntPatch_TheSegmentOfTheSOnBounds thesegsol;
1339   IntPatch_ThePathPointOfTheSOnBounds PStartf,PStartl;
1340   Standard_Boolean dofirst,dolast,procf,procl;
1341 
1342   Standard_Real paramf =0.,paraml =0.,U1 =0.,V1 =0.,U2 =0.,V2 =0.;
1343 
1344   IntPatch_IType typ;
1345   IntSurf_TypeTrans trans1,trans2;
1346   IntSurf_Transition TRest,TArc;
1347   gp_Vec tgline,norm1,norm2,tgarc;
1348   gp_Pnt valpt;
1349 
1350   gp_Vec d1u,d1v;
1351   gp_Pnt2d p2d;
1352   gp_Vec2d d2d;
1353 
1354 
1355   for (i = 1; i <= nbedg; i++) {
1356     Standard_Boolean EdgeDegenere=Standard_False;
1357     thesegsol = listedg.Value(i);
1358     arcRef = thesegsol.Curve();
1359 
1360 
1361     rline = new IntPatch_RLine(Standard_False);
1362     if(OnFirst) { 
1363       rline->SetArcOnS1(arcRef);
1364     }
1365     else { 
1366       rline->SetArcOnS2(arcRef);
1367     }
1368 
1369 // Traitement des points debut/fin du segment solution.
1370 
1371     dofirst = Standard_False;
1372     dolast  = Standard_False;
1373     procf = Standard_False;
1374     procl = Standard_False;
1375 
1376     if (thesegsol.HasFirstPoint()) {
1377       dofirst = Standard_True;
1378       PStartf = thesegsol.FirstPoint();
1379       paramf = PStartf.Parameter();
1380     }
1381     if (thesegsol.HasLastPoint()) {
1382       dolast = Standard_True;
1383       PStartl = thesegsol.LastPoint();
1384       paraml = PStartl.Parameter();
1385     }
1386 
1387     if (dofirst && dolast) { // determination de la transition de la ligne
1388       arcRef->D1(0.5*(paramf+paraml),p2d,d2d);
1389       if (OnFirst) {
1390         Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1391       }
1392       else {
1393         Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1394       }
1395       tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1396 
1397       if(d1u.Magnitude()<1e-7) { //-- edge degenere ?
1398          EdgeDegenere=Standard_True;
1399         for(Standard_Integer edg=0;edg<=10;edg++) {
1400           arcRef->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
1401           if (OnFirst) {
1402             Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1403           }
1404           else {
1405             Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1406           }
1407           
1408           if(d1u.Magnitude()>1e-7) {
1409             EdgeDegenere=Standard_False;
1410           }
1411         }
1412         rline = new IntPatch_RLine(Standard_False);     
1413         if(OnFirst) { 
1414           rline->SetArcOnS1(arcRef);
1415         }
1416         else { 
1417           rline->SetArcOnS2(arcRef);
1418         }       
1419       }
1420       else { 
1421         norm2 = Quad2.Normale(valpt);
1422         norm1 = Quad1.Normale(valpt);
1423         
1424         if (tgline.DotCross(norm2,norm1) > 0.000000001) {
1425           trans1 = IntSurf_Out;
1426           trans2 = IntSurf_In;
1427         }
1428         else if (tgline.DotCross(norm2,norm1) < -0.000000001){
1429           trans1 = IntSurf_In;
1430           trans2 = IntSurf_Out;
1431         }
1432         else { 
1433           trans1 = trans2 = IntSurf_Undecided;
1434         }
1435         rline = new IntPatch_RLine(Standard_False,trans1,trans2);
1436         if(OnFirst) { 
1437           rline->SetArcOnS1(arcRef);
1438         }
1439         else { 
1440           rline->SetArcOnS2(arcRef);
1441         }       
1442       }
1443     }
1444     else {
1445       rline = new IntPatch_RLine(Standard_False);
1446       if(OnFirst) { 
1447         rline->SetArcOnS1(arcRef);
1448       }
1449       else { 
1450         rline->SetArcOnS2(arcRef);
1451       } 
1452     }
1453 
1454     if (dofirst || dolast) {
1455       Nblines = slin.Length();
1456       for (j=1; j<=Nblines; j++) {
1457         const Handle(IntPatch_Line)& slinj = slin(j);
1458         typ = slinj->ArcType();
1459         if (typ == IntPatch_Analytic) {
1460           Nbpts = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
1461         }
1462         else if (typ == IntPatch_Restriction) {
1463           Nbpts = Handle(IntPatch_RLine)::DownCast (slinj)->NbVertex();
1464         }
1465         else {
1466           Nbpts = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
1467         }
1468         for (k=1; k<=Nbpts;k++) {
1469           if (typ == IntPatch_Analytic) {
1470             ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
1471           }
1472           else if (typ == IntPatch_Restriction) {
1473             ptvtx = Handle(IntPatch_RLine)::DownCast (slinj)->Vertex(k);
1474           }
1475           else {
1476             ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
1477           }
1478           
1479           if (EdgeDegenere==Standard_False && dofirst) {
1480             if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
1481               ptvtx.SetMultiple(Standard_True);
1482               ptvtx.SetTolerance(TolArc);
1483               if (typ == IntPatch_Analytic) {
1484                 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
1485               }
1486               else if (typ == IntPatch_Restriction) {
1487                 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
1488               }
1489               else {
1490                 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
1491               }
1492               newptvtx = ptvtx;
1493               newptvtx.SetParameter(paramf);
1494               //Recalcul des  transitions si point sur restriction
1495 
1496               arcRef->D1(paramf,p2d,d2d);
1497               if (OnFirst) {
1498                 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1499               }
1500               else {
1501                 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1502               }
1503               tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1504               if (ptvtx.IsOnDomS1()) {
1505                 const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS1();
1506                 thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
1507                 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1508                 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
1509                 norm1 = d1u.Crossed(d1v); 
1510                 if(norm1.SquareMagnitude()<1e-16) { 
1511                   TRest.SetValue(Standard_True,IntSurf_Undecided);
1512                   TArc.SetValue(Standard_True,IntSurf_Undecided);           
1513                 }
1514                 else {          
1515                   IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
1516                 }
1517                 newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
1518                                 TRest,TArc);
1519               }
1520               if (ptvtx.IsOnDomS2()) {
1521                 const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS2();
1522                 thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
1523                 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1524                 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
1525                 norm2 = d1u.Crossed(d1v);
1526                 if(norm2.SquareMagnitude()<1e-16) { 
1527                   TRest.SetValue(Standard_True,IntSurf_Undecided);
1528                   TArc.SetValue(Standard_True,IntSurf_Undecided);           
1529                 }
1530                 else {                            
1531                   IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
1532                 }
1533                 newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
1534                                 TRest,TArc);
1535               }
1536 
1537               rline->AddVertex(newptvtx);
1538               if (!procf){
1539                 procf=Standard_True;
1540                 rline->SetFirstPoint(rline->NbVertex());
1541               }
1542             }
1543           }
1544           if (EdgeDegenere==Standard_False && dolast) {
1545             if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
1546               ptvtx.SetMultiple(Standard_True);
1547               ptvtx.SetTolerance(TolArc);
1548               if (typ == IntPatch_Analytic) {
1549                 Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,ptvtx);
1550               }
1551               else if (typ == IntPatch_Restriction) {
1552                 Handle(IntPatch_RLine)::DownCast (slinj)->Replace(k,ptvtx);
1553               }
1554               else {
1555                 Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,ptvtx);
1556               }
1557 
1558               newptvtx = ptvtx;
1559               newptvtx.SetParameter(paraml);
1560               //Recalcul des  transitions si point sur restriction
1561 
1562               arcRef->D1(paraml,p2d,d2d);
1563               if (OnFirst) {
1564                 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1565               }
1566               else {
1567                 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1568               }
1569               tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1570               if (ptvtx.IsOnDomS1()) {
1571                 const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS1();
1572                 thearc->D1(ptvtx.ParameterOnArc1(),p2d,d2d);
1573                 Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1574                 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
1575                 norm1 = d1u.Crossed(d1v);
1576                 if(norm1.SquareMagnitude()<1e-16) { 
1577                   TRest.SetValue(Standard_True,IntSurf_Undecided);
1578                   TArc.SetValue(Standard_True,IntSurf_Undecided);           
1579                 }
1580                 else {          
1581                   IntSurf::MakeTransition(tgline,tgarc,norm1,TRest,TArc);
1582                 }
1583                 newptvtx.SetArc(Standard_True,thearc,ptvtx.ParameterOnArc1(),
1584                                 TRest,TArc);
1585               }
1586               if (ptvtx.IsOnDomS2()) {
1587                 const Handle(Adaptor2d_Curve2d)& thearc = ptvtx.ArcOnS2();
1588                 thearc->D1(ptvtx.ParameterOnArc2(),p2d,d2d);
1589                 Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1590                 tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
1591                 norm2 = d1u.Crossed(d1v);
1592                 if(norm2.SquareMagnitude()<1e-16) { 
1593                   TRest.SetValue(Standard_True,IntSurf_Undecided);
1594                   TArc.SetValue(Standard_True,IntSurf_Undecided);           
1595                 }
1596                 else {                        
1597                   IntSurf::MakeTransition(tgline,tgarc,norm2,TRest,TArc);
1598                 }
1599                 newptvtx.SetArc(Standard_False,thearc,ptvtx.ParameterOnArc2(),
1600                                 TRest,TArc);
1601               }
1602 
1603               rline->AddVertex(newptvtx);
1604               if (!procl){
1605                 procl=Standard_True;
1606                 rline->SetLastPoint(rline->NbVertex());
1607               }
1608             }
1609           }
1610         }
1611 // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
1612 // il (ils) correspond(ent) a un point multiple.
1613 
1614         if (procf) {
1615           dofirst = Standard_False;
1616         }
1617         if (procl) {
1618           dolast  = Standard_False;
1619         }
1620       }
1621     }
1622 // Si on n a pas trouve le point debut et./ou fin sur une des lignes
1623 // d intersection, il faut quand-meme le placer sur la restriction solution
1624 
1625     if (dofirst) {
1626       ptvtx.SetValue(PStartf.Value(),PStartf.Tolerance(),Standard_False);
1627       Quad1.Parameters(PStartf.Value(),U1,V1);
1628       Quad2.Parameters(PStartf.Value(),U2,V2);
1629       ptvtx.SetParameters(U1,V1,U2,V2);
1630       ptvtx.SetParameter(paramf);
1631       if (! PStartf.IsNew()) {
1632         IntSurf_Transition Transline;
1633         IntSurf_Transition Transarc;
1634         ptvtx.SetVertex(OnFirst,PStartf.Vertex());
1635         ptvtx.SetArc(OnFirst,PStartf.Arc(),PStartf.Parameter(),
1636                      Transline,Transarc);
1637       }
1638 
1639       rline->AddVertex(ptvtx);
1640       rline->SetFirstPoint(rline->NbVertex());
1641     }
1642     if (dolast) {
1643       ptvtx.SetValue(PStartl.Value(),PStartl.Tolerance(),Standard_False);
1644       Quad1.Parameters(PStartl.Value(),U1,V1);
1645       Quad2.Parameters(PStartl.Value(),U2,V2);
1646       ptvtx.SetParameters(U1,V1,U2,V2);
1647       ptvtx.SetParameter(paraml);
1648       if (! PStartl.IsNew()) {
1649         IntSurf_Transition Transline;
1650         IntSurf_Transition Transarc;
1651 
1652         ptvtx.SetVertex(OnFirst,PStartl.Vertex());
1653         ptvtx.SetArc(OnFirst,PStartl.Arc(),PStartl.Parameter(),
1654                      Transline,Transarc);
1655       }
1656 
1657       rline->AddVertex(ptvtx);
1658       rline->SetLastPoint(rline->NbVertex());
1659     }
1660     slin.Append(rline);
1661   }
1662 }
1663 
1664 inline const gp_Pnt& PointValue(const Handle(IntPatch_RLine) theRLine,
1665                                 const Standard_Integer theIndex)
1666 {
1667   return theRLine->Point(theIndex).Value();
1668 }
1669 
1670 inline const gp_Pnt& VertexValue( const Handle(IntPatch_RLine) theRLine,
1671                                   const Standard_Integer theIndex)
1672 {
1673   return theRLine->Vertex(theIndex).Value();
1674 }
1675 
1676 static Standard_Real SquareDistance(const Handle(IntPatch_GLine)& theGLine,
1677                                     const gp_Pnt& theP,
1678                                     Extrema_ExtPC& theExtr)
1679 {
1680   Standard_Real aSQDist = RealLast();
1681   switch(theGLine->ArcType())
1682   {
1683   case IntPatch_Lin:
1684     aSQDist = theGLine->Line().SquareDistance(theP);
1685     break;
1686   case IntPatch_Circle:
1687     aSQDist = theGLine->Circle().SquareDistance(theP);
1688     break;
1689   default:
1690     theExtr.Perform(theP);
1691     if(!theExtr.IsDone() || !theExtr.NbExt())
1692     {
1693       //Lines are not overlapped
1694       return aSQDist;
1695     }
1696 
1697     aSQDist = theExtr.SquareDistance(1);
1698     const Standard_Integer aNbExtr = theExtr.NbExt();
1699     for ( Standard_Integer i = 2; i <= aNbExtr; i++)
1700     {
1701       const Standard_Real aSQD = theExtr.SquareDistance(i);
1702       if (aSQD < aSQDist)
1703       {
1704         aSQDist = aSQD;
1705       }
1706     }
1707   }
1708 
1709   return aSQDist;
1710 }
1711 
1712 static Standard_Boolean IsRLineGood(const IntSurf_Quadric& Quad1,
1713                                     const IntSurf_Quadric& Quad2,
1714                                     const Handle(IntPatch_GLine) theGLine,
1715                                     const Handle(IntPatch_RLine) theRLine,
1716                                     const Standard_Real theTol)
1717 {
1718   const Standard_Real aSQTol = theTol*theTol;
1719   const IntPatch_IType aGType = theGLine->ArcType();
1720   Standard_Integer aNbPntsM1 = 0;
1721   
1722   const gp_Pnt& (*Value) (const Handle(IntPatch_RLine), const Standard_Integer);
1723 
1724   if(theRLine->HasPolygon())
1725   {
1726     aNbPntsM1 = theRLine->NbPnts()-1;
1727     Value = PointValue;
1728   }
1729   else
1730   {
1731     aNbPntsM1 = theRLine->NbVertex()-1;
1732     Value = VertexValue;
1733   }
1734   
1735   if(aNbPntsM1 < 1)
1736     return Standard_False;
1737 
1738   Extrema_ExtPC anExtr;
1739   GeomAdaptor_Curve anAC;
1740   Handle(Geom_Curve) aCurv;
1741 
1742   if(aGType == IntPatch_Ellipse)
1743     aCurv = new Geom_Ellipse(theGLine->Ellipse());
1744   else if(aGType == IntPatch_Parabola)
1745     aCurv = new Geom_Parabola(theGLine->Parabola());
1746   else if(aGType == IntPatch_Hyperbola)
1747     aCurv = new Geom_Hyperbola(theGLine->Hyperbola());
1748   
1749   if(!aCurv.IsNull())
1750   {
1751     const Standard_Real anUinf = aCurv->FirstParameter(),
1752                         anUsup = aCurv->LastParameter();
1753     anAC.Load(aCurv, anUinf, anUsup);
1754     anExtr.Initialize(anAC, anUinf, anUsup);
1755   }
1756 
1757   if(aNbPntsM1 == 1)
1758   {
1759     gp_Pnt aP1(Value(theRLine, 1)), aP2(Value(theRLine, 2));
1760 
1761     if(aP1.SquareDistance(aP2) < aSQTol)
1762     {
1763       //RLine is degenerated
1764       return Standard_False;
1765     }
1766 
1767     gp_Pnt aPMid;
1768     if(theRLine->IsArcOnS1())
1769     {
1770       const Handle(Adaptor2d_Curve2d)& anAC2d = theRLine->ArcOnS1();
1771       const Standard_Real aParF = anAC2d->FirstParameter(),
1772                           aParL = anAC2d->LastParameter();
1773       gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
1774       aPMid = Quad1.Value(aP2d.X(), aP2d.Y());
1775     }
1776     else
1777     {
1778       const Handle(Adaptor2d_Curve2d)& anAC2d = theRLine->ArcOnS2();
1779       const Standard_Real aParF = anAC2d->FirstParameter(),
1780                           aParL = anAC2d->LastParameter();
1781       gp_Pnt2d aP2d(anAC2d->Value(0.5*(aParF+aParL)));
1782       aPMid = Quad2.Value(aP2d.X(), aP2d.Y());
1783     }
1784 
1785     const Standard_Real aSQDist = SquareDistance(theGLine, aPMid, anExtr);
1786     return (aSQDist > aSQTol);
1787   }
1788 
1789   for(Standard_Integer i = 2; i <= aNbPntsM1; i++)
1790   {
1791     const gp_Pnt aP(Value(theRLine, i));
1792     const Standard_Real aSQDist = SquareDistance(theGLine, aP, anExtr);
1793 
1794     if(aSQDist > aSQTol)
1795       return Standard_True;
1796   }
1797 
1798   return Standard_False;
1799 }
1800                                       
1801 
1802 void ProcessRLine (IntPatch_SequenceOfLine& slin,
1803 //                 const Handle(Adaptor3d_Surface)& Surf1,
1804 //                 const Handle(Adaptor3d_Surface)& Surf2,
1805                    const IntSurf_Quadric& Quad1,
1806                    const IntSurf_Quadric& Quad2,
1807                    const Standard_Real _TolArc,
1808                    const Standard_Boolean theIsReqToKeepRLine) {
1809 
1810 // On cherche a placer sur les restrictions solutions les points "multiples"
1811 // des autres lignes d intersection
1812 // Pas forcemment le plus efficace : on rique de projeter plusieurs fois
1813 // le meme point sur la meme restriction...
1814 
1815   Standard_Real TolArc=100.0*_TolArc;
1816   if(TolArc>0.1) TolArc=0.1;
1817   
1818   Standard_Integer i,j,k;
1819   Standard_Integer Nblin,Nbvtx, Nbpt;
1820 
1821   Standard_Boolean OnFirst = Standard_False,project = Standard_False,keeppoint = Standard_False;
1822 
1823   Handle(Adaptor2d_Curve2d) arcref;
1824   Standard_Real paramproj,paramf,paraml;
1825 
1826   TColgp_SequenceOfPnt seq_Pnt3d;
1827   TColStd_SequenceOfReal seq_Real;
1828 
1829   gp_Pnt ptproj,toproj,valpt;
1830 
1831   gp_Pnt2d p2d;
1832   gp_Vec2d d2d;
1833   gp_Vec d1u,d1v,tgrest,tgarc,norm;
1834   IntSurf_Transition TRest,TArc;
1835 #ifndef OCCT_DEBUG
1836   Standard_Real U =0.,V =0.;
1837 #else
1838   Standard_Real U,V;
1839 #endif
1840   IntPatch_Point Ptvtx,newptvtx;
1841 
1842   IntPatch_IType typ1,typ2;
1843 
1844 
1845   Nblin = slin.Length();
1846   for (i=1; i<=Nblin; i++) {
1847     const Handle(IntPatch_Line)& slini = slin(i);
1848     typ1 = slini->ArcType();
1849 
1850     Standard_Boolean HasToDeleteRLine = Standard_False;
1851     if (typ1 == IntPatch_Restriction) {
1852       seq_Pnt3d.Clear();
1853       seq_Real.Clear();
1854       
1855       for (j=1; j<=Nblin; j++) {
1856         const  Handle(IntPatch_Line)& slinj = slin(j);
1857         Nbpt = seq_Pnt3d.Length();      // important que ce soit ici
1858         typ2 = slinj->ArcType();
1859         if (typ2 != IntPatch_Restriction) {
1860           //-- arcref = Handle(IntPatch_RLine)::DownCast (slini)->Arc();
1861           //-- OnFirst = Handle(IntPatch_RLine)::DownCast (slini)->IsOnFirstSurface();
1862 
1863           //-- DES CHOSES A FAIRE ICI 
1864           if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS1()) { 
1865             OnFirst=Standard_True;
1866             arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS1();
1867           }
1868           else if(Handle(IntPatch_RLine)::DownCast (slini)->IsArcOnS2()) { 
1869             arcref= Handle(IntPatch_RLine)::DownCast (slini)->ArcOnS2();
1870             OnFirst=Standard_False;
1871           }
1872           if (Handle(IntPatch_RLine)::DownCast (slini)->HasFirstPoint()) {
1873             paramf = Handle(IntPatch_RLine)::DownCast (slini)->FirstPoint().ParameterOnLine();
1874           }
1875           else {
1876             // cout << "Pas de param debut sur rst solution" << endl;
1877             paramf = RealFirst();
1878           }
1879           if (Handle(IntPatch_RLine)::DownCast (slini)->HasLastPoint()) {
1880             paraml = Handle(IntPatch_RLine)::DownCast (slini)->LastPoint().ParameterOnLine();
1881           }
1882           else {
1883             // cout << "Pas de param debut sur rst solution" << endl;
1884             paraml = RealLast();
1885           }
1886 
1887           if (typ2 == IntPatch_Analytic) {
1888             Nbvtx = Handle(IntPatch_ALine)::DownCast (slinj)->NbVertex();
1889           }
1890           else {
1891             Nbvtx = Handle(IntPatch_GLine)::DownCast (slinj)->NbVertex();
1892           }
1893 
1894           
1895           Standard_Boolean EdgeDegenere=Standard_True;
1896           for(Standard_Integer edg=0;EdgeDegenere && edg<=10;edg++) {
1897             arcref->D1(paramf+(paraml-paramf)*edg*0.1,p2d,d2d);
1898             if (OnFirst) {
1899               Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1900             }
1901             else {
1902               Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
1903             }
1904             if(d1u.Magnitude()>1e-7) {
1905               EdgeDegenere=Standard_False;
1906             }
1907           } 
1908 
1909           for (k=1; EdgeDegenere==Standard_False && k<=Nbvtx; k++) {
1910             if (typ2 == IntPatch_Analytic) {
1911               Ptvtx = Handle(IntPatch_ALine)::DownCast (slinj)->Vertex(k);
1912             }
1913             else {
1914               Ptvtx = Handle(IntPatch_GLine)::DownCast (slinj)->Vertex(k);
1915             }
1916             if ((OnFirst && !Ptvtx.IsOnDomS1()) ||
1917                 (!OnFirst && !Ptvtx.IsOnDomS2())) {
1918               // Si OnFirst && OnDomS1, c est qu on est a une extremite
1919               // ca doit etre traite par Process Segment...
1920               project = Standard_True;
1921               keeppoint = Standard_False;
1922               toproj = Ptvtx.Value();
1923               
1924               Standard_Integer jj;
1925               for (jj = 1; jj <= Nbpt; jj++) {
1926               //for (Standard_Integer jj = 1; jj <= Nbpt; jj++) {
1927                 if (toproj.Distance(seq_Pnt3d(jj)) < _TolArc) {
1928                   project = Standard_False; 
1929                   break;
1930                 }
1931               }
1932               if (project) { //-- il faut projeter pour trouver le point sur la rline. 
1933                 if (OnFirst) {   
1934                   Ptvtx.ParametersOnS1(U,V); 
1935                 }
1936                 else {
1937                   Ptvtx.ParametersOnS2(U,V);
1938                 }
1939 
1940                 project = IntPatch_HInterTool::Project(arcref,gp_Pnt2d(U,V),
1941                                                 paramproj,p2d);
1942                 
1943                 if (project) {
1944                   if (OnFirst) {
1945                     ptproj = Quad1.Value(p2d.X(),p2d.Y());
1946                   }
1947                   else {
1948                     ptproj = Quad2.Value(p2d.X(),p2d.Y());
1949                   }
1950                   if ((toproj.Distance(ptproj) <=100*TolArc) &&
1951                       (paramproj >= paramf) && (paramproj <= paraml)){
1952                     newptvtx = Ptvtx;
1953                     newptvtx.SetParameter(paramproj);
1954                     keeppoint = Standard_True;
1955                     seq_Pnt3d.Append(toproj);
1956                     seq_Real.Append(paramproj);
1957                     
1958                     //-- verifier que si la restriction arcref est trouvee, elle porte ce vertex
1959                     for (int ri=1; ri<=Nblin; ri++) {
1960                       const Handle(IntPatch_Line)& slinri = slin(ri);
1961                       if (slinri->ArcType() == IntPatch_Restriction) {
1962                         if(OnFirst && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS1()) { 
1963                           if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS1()) { 
1964                             Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
1965                             //printf("\n ImpImpIntersection_0.gxx CAS1 \n");
1966                           }
1967                         }
1968                         else if(OnFirst==Standard_False && Handle(IntPatch_RLine)::DownCast (slinri)->IsArcOnS2()) { 
1969                           if(arcref == Handle(IntPatch_RLine)::DownCast (slinri)->ArcOnS2()) { 
1970                             Handle(IntPatch_RLine)::DownCast (slinri)->AddVertex(newptvtx);
1971                             //printf("\n ImpImpIntersection_0.gxx CAS2 \n");
1972                           }
1973                         }
1974                       }
1975                     }
1976                     // -- --------------------------------------------------
1977                   }
1978                 }
1979               }
1980               else {
1981                 keeppoint = Standard_True;
1982                 newptvtx = Ptvtx;
1983                 newptvtx.SetParameter(seq_Real(jj));
1984               }
1985               if (keeppoint) {
1986                 Ptvtx.SetMultiple(Standard_True);
1987                 Ptvtx.SetTolerance(_TolArc);
1988                 newptvtx.SetMultiple(Standard_True);
1989                 
1990                 if (typ2 == IntPatch_Analytic) {
1991                   Handle(IntPatch_ALine)::DownCast (slinj)->Replace(k,Ptvtx);
1992                 }
1993                 else {
1994                   Handle(IntPatch_GLine)::DownCast (slinj)->Replace(k,Ptvtx);
1995                 }
1996 
1997                 if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2()) {
1998                 
1999                   arcref->D1(newptvtx.ParameterOnLine(),p2d,d2d);
2000                 
2001                   if (OnFirst) { // donc OnDomS2
2002                     Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2003                     tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2004 
2005                     const Handle(Adaptor2d_Curve2d)& thearc = Ptvtx.ArcOnS2();
2006                     thearc->D1(Ptvtx.ParameterOnArc2(),p2d,d2d);
2007                     Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2008                     tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
2009                     norm = d1u.Crossed(d1v); //Quad2.Normale(valpt);
2010                     if(norm.SquareMagnitude()<1e-16) { 
2011                       TRest.SetValue(Standard_True,IntSurf_Undecided);
2012                       TArc.SetValue(Standard_True,IntSurf_Undecided);       
2013                     }
2014                     else {                                    
2015                       IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
2016                     }
2017                     newptvtx.SetArc(Standard_False,thearc,
2018                                     Ptvtx.ParameterOnArc2(),TRest,TArc);
2019 
2020                   }
2021                   else { // donc OnDomS1
2022                     Quad2.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2023                     tgrest.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
2024 
2025                     const Handle(Adaptor2d_Curve2d)& thearc = Ptvtx.ArcOnS1();
2026                     thearc->D1(Ptvtx.ParameterOnArc1(),p2d,d2d);
2027                     Quad1.D1(p2d.X(),p2d.Y(),valpt,d1u,d1v);
2028                     tgarc.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v); 
2029                     norm = d1u.Crossed(d1v); //Quad1.Normale(valpt);
2030                     if(norm.SquareMagnitude()<1e-16) { 
2031                       TRest.SetValue(Standard_True,IntSurf_Undecided);
2032                       TArc.SetValue(Standard_True,IntSurf_Undecided);       
2033                     }
2034                     else {              
2035                       IntSurf::MakeTransition(tgrest,tgarc,norm,TRest,TArc);
2036                     }
2037                     newptvtx.SetArc(Standard_True,thearc,
2038                                     Ptvtx.ParameterOnArc1(),TRest,TArc);
2039                   }
2040                 } //-- if (Ptvtx.IsOnDomS1() || Ptvtx.IsOnDomS2())
2041 
2042                 Handle(IntPatch_RLine)::DownCast (slini)->AddVertex(newptvtx);
2043 
2044               } //-- if (keeppoint)
2045             } //-- if ((OnFirst && !Ptvtx.IsOnDomS1())||(!OnFirst && !Ptvtx.IsOnDomS2()))
2046           } //-- boucle sur les vertex
2047 
2048           if(!theIsReqToKeepRLine)
2049           {
2050             Handle(IntPatch_GLine) aGL = Handle(IntPatch_GLine)::DownCast(slinj);
2051 
2052             if(!aGL.IsNull())
2053             {
2054               HasToDeleteRLine = !IsRLineGood(Quad1, Quad2, aGL, 
2055                                         Handle(IntPatch_RLine)::DownCast(slini), TolArc);
2056             }
2057 
2058             if(HasToDeleteRLine)
2059             {
2060               break;
2061             }
2062           }
2063         } //-- if (typ2 != IntPatch_Restriction)
2064       } //-- for (j=1; j<=Nblin; j++) 
2065     } //-- if (typ1 == IntPatch_Restriction)
2066 
2067     if(HasToDeleteRLine)
2068     {
2069       slin.Remove(i);
2070       i--;
2071       Nblin = slin.Length();
2072       continue;
2073     }
2074   } //-- for (i=1; i<=Nblin; i++)
2075 }