Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Created on: 1993-03-22
0002 // Created by: Laurent BUCHARD
0003 // Copyright (c) 1993-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 #include <TColStd_Array1OfReal.hxx>
0018 #include <gp_Pnt2d.hxx>
0019 #include <gp_Pnt.hxx>
0020 #include <gp_Vec2d.hxx>
0021 #include <gp_Vec.hxx>
0022 #include <IntSurf_LineOn2S.hxx>
0023 #include <Precision.hxx>
0024 #include <math_Vector.hxx>
0025 
0026 #ifdef DRAW
0027 #include <DrawTrSurf.hxx>
0028 #endif
0029 
0030 //=======================================================================
0031 //function : Constructor
0032 //purpose  : 
0033 //=======================================================================
0034 ApproxInt_MultiLine::ApproxInt_MultiLine()
0035 {
0036   PtrOnmySvSurfaces = NULL;
0037   myLine = NULL;
0038   indicemin = 0;
0039   indicemax = 0;
0040   nbp3d = 0;
0041   nbp2d = 0;
0042   myApproxU1V1 = Standard_False;
0043   myApproxU2V2 = Standard_False;
0044   p2donfirst = Standard_True;
0045   Xo = 0.;
0046   Yo = 0.;
0047   Zo = 0.;
0048   U1o = 0.;
0049   V1o = 0.;
0050   U2o = 0.;
0051   V2o = 0.;
0052 }
0053 
0054 //=======================================================================
0055 //function : Constructor
0056 //purpose  : 
0057 //=======================================================================
0058 ApproxInt_MultiLine::
0059   ApproxInt_MultiLine(const Handle_TheLine& line,
0060                       const Standard_Address svsurf,
0061                       const Standard_Integer NbP3d,
0062                       const Standard_Integer NbP2d,
0063                       const Standard_Boolean ApproxU1V1,
0064                       const Standard_Boolean ApproxU2V2,
0065                       const Standard_Real xo,
0066                       const Standard_Real yo,
0067                       const Standard_Real zo,
0068                       const Standard_Real u1o,
0069                       const Standard_Real v1o,
0070                       const Standard_Real u2o,
0071                       const Standard_Real v2o,
0072                       const Standard_Boolean P2DOnFirst,
0073                       const Standard_Integer IndMin,
0074                       const Standard_Integer IndMax): PtrOnmySvSurfaces(svsurf),
0075                                                       myLine(line),
0076                                                       indicemin(Min(IndMin, IndMax)),
0077                                                       indicemax(Max(IndMin, IndMax)),
0078                                                       nbp3d(NbP3d), nbp2d(NbP2d),
0079                                                       myApproxU1V1(ApproxU1V1),
0080                                                       myApproxU2V2(ApproxU2V2),
0081                                                       p2donfirst(P2DOnFirst),
0082                                                       Xo(xo), Yo(yo), Zo(zo),
0083                                                       U1o(u1o), V1o(v1o),
0084                                                       U2o(u2o), V2o(v2o)
0085 
0086 {
0087 #ifdef OCCT_DEBUG
0088   //if(indicemin == indicemax)
0089   //{
0090   //  cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
0091   //}
0092 #endif
0093 }
0094 
0095 //=======================================================================
0096 //function : Constructor
0097 //purpose  : 
0098 //=======================================================================
0099 ApproxInt_MultiLine::
0100   ApproxInt_MultiLine(const Handle_TheLine& line,
0101                       const Standard_Integer NbP3d,
0102                       const Standard_Integer NbP2d,
0103                       const Standard_Boolean ApproxU1V1,
0104                       const Standard_Boolean ApproxU2V2,
0105                       const Standard_Real xo,
0106                       const Standard_Real yo,
0107                       const Standard_Real zo,
0108                       const Standard_Real u1o,
0109                       const Standard_Real v1o,
0110                       const Standard_Real u2o,
0111                       const Standard_Real v2o,
0112                       const Standard_Boolean P2DOnFirst,
0113                       const Standard_Integer IndMin,
0114                       const Standard_Integer IndMax): PtrOnmySvSurfaces(0),
0115                                                       myLine(line),
0116                                                       indicemin(Min(IndMin, IndMax)),
0117                                                       indicemax(Max(IndMin, IndMax)),
0118                                                       nbp3d(NbP3d), nbp2d(NbP2d),
0119                                                       myApproxU1V1(ApproxU1V1),
0120                                                       myApproxU2V2(ApproxU2V2),
0121                                                       p2donfirst(P2DOnFirst),
0122                                                       Xo(xo), Yo(yo), Zo(zo),
0123                                                       U1o(u1o), V1o(v1o),
0124                                                       U2o(u2o), V2o(v2o)
0125 {
0126 #ifdef OCCT_DEBUG
0127   //if(indicemin == indicemax)
0128   //{
0129   //  cout<<"ApproxInt_MultiLine: indicemin = indicemax = " << indicemin << endl;
0130   //}
0131 #endif
0132 }
0133 
0134 //--------------------------------------------------------------------------------
0135 Standard_Integer ApproxInt_MultiLine::FirstPoint() const { 
0136   return indicemin;
0137 }
0138 //--------------------------------------------------------------------------------
0139 Standard_Integer ApproxInt_MultiLine::LastPoint() const { 
0140   return indicemax;
0141 }
0142 //--------------------------------------------------------------------------------
0143 Approx_Status ApproxInt_MultiLine::WhatStatus() const { 
0144   if(PtrOnmySvSurfaces)
0145     return Approx_PointsAdded;
0146   else 
0147     return Approx_NoPointsAdded;
0148 }
0149 //--------------------------------------------------------------------------------
0150 Standard_Integer ApproxInt_MultiLine::NbP3d() const { 
0151   return nbp3d;
0152 }
0153 //--------------------------------------------------------------------------------
0154 Standard_Integer ApproxInt_MultiLine::NbP2d() const { 
0155   return nbp2d;
0156 }
0157 //================================================================================
0158 void ApproxInt_MultiLine::Value(const Standard_Integer  Index,
0159                                 TColgp_Array1OfPnt&     TabPnt)  const
0160 {
0161   const gp_Pnt aP = myLine->Point(Index).Value();
0162   TabPnt(1).SetCoord(aP.X()+Xo, aP.Y()+Yo, aP.Z()+Zo);
0163 }
0164 
0165 //=======================================================================
0166 //function : Value
0167 //purpose  : 
0168 //=======================================================================
0169 void ApproxInt_MultiLine::Value(const Standard_Integer Index,
0170                                 TColgp_Array1OfPnt2d&  TabPnt2d) const 
0171 {
0172   IntSurf_PntOn2S POn2S(myLine->Point(Index));
0173   Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
0174   POn2S.Parameters(u1, v1, u2, v2);
0175   if(nbp2d==1)
0176   { 
0177     if(p2donfirst)
0178     { 
0179       TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
0180     }
0181     else
0182     {
0183       TabPnt2d(1).SetCoord(u2+U2o, v2+V2o);
0184     }
0185   }
0186   else
0187   {
0188     TabPnt2d(1).SetCoord(u1+U1o, v1+V1o);
0189     if(TabPnt2d.Length() >= 2)
0190     { 
0191       TabPnt2d(2).SetCoord(u2+U2o, v2+V2o);
0192     } 
0193   }
0194 }
0195 
0196 //=======================================================================
0197 //function : Value
0198 //purpose  : 
0199 //=======================================================================
0200 void ApproxInt_MultiLine::Value(const Standard_Integer Index,
0201                                 TColgp_Array1OfPnt&    TabPnt,
0202                                 TColgp_Array1OfPnt2d&  TabPnt2d)  const 
0203 { 
0204     Value(Index, TabPnt);
0205     Value(Index, TabPnt2d);
0206 }
0207 
0208 //=======================================================================
0209 //function : Tangency
0210 //purpose  : 
0211 //=======================================================================
0212 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
0213                                                 TColgp_Array1OfVec&    TabVec) const 
0214 {
0215   if(PtrOnmySvSurfaces==NULL) 
0216     return Standard_False;
0217 
0218   const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
0219   Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
0220   POn2S.Parameters(u1,v1,u2,v2);
0221 
0222   Standard_Boolean ret=
0223             ((TheSvSurfaces *)PtrOnmySvSurfaces)->Tangency(u1, v1, u2, v2, TabVec(1));
0224   if(!ret)
0225   {
0226     TabVec(1).SetCoord(0.0, 0.0, 0.0);
0227   }
0228 
0229   return ret;
0230 }
0231 
0232 //=======================================================================
0233 //function : Tangency
0234 //purpose  : 
0235 //=======================================================================
0236 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
0237                                                 TColgp_Array1OfVec2d&  TabVec2d) const 
0238 {
0239   if(PtrOnmySvSurfaces==NULL) 
0240     return Standard_False;
0241 
0242   const IntSurf_PntOn2S& POn2S = myLine->Point(Index);
0243   Standard_Real u1 = 0.0, u2 = 0.0, v1 = 0.0, v2 = 0.0;
0244   POn2S.Parameters(u1,v1,u2,v2);
0245 
0246   Standard_Boolean ret = Standard_False;
0247   if(nbp2d==1)
0248   { 
0249     if(p2donfirst)
0250     {
0251       ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
0252     }
0253     else
0254     { 
0255       ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(1));
0256     }
0257   }
0258   else
0259   {
0260     ret=((TheSvSurfaces *)PtrOnmySvSurfaces)->TangencyOnSurf1(u1, v1, u2, v2, TabVec2d(1));
0261     if(ret)
0262     { 
0263       if(TabVec2d.Length()>=2)
0264       {
0265         ret = 
0266               (ret && 
0267               ((TheSvSurfaces *)PtrOnmySvSurfaces)->
0268                                           TangencyOnSurf2(u1, v1, u2, v2, TabVec2d(2)));
0269       }
0270     }
0271   }
0272 
0273   if(!ret)
0274   {
0275     TabVec2d(1) = gp_Vec2d(0.0, 0.0);
0276     if(TabVec2d.Length() >= 2)
0277     {
0278       TabVec2d(2) = gp_Vec2d(0.0,0.0);
0279     }
0280   }
0281 
0282   return ret;
0283 }
0284 
0285 //=======================================================================
0286 //function : Tangency
0287 //purpose  : 
0288 //=======================================================================
0289 Standard_Boolean ApproxInt_MultiLine::Tangency( const Standard_Integer Index,
0290                                                 TColgp_Array1OfVec& TabVec,
0291                                                 TColgp_Array1OfVec2d& TabVec2d) const
0292 { 
0293   return (Tangency(Index, TabVec) && Tangency(Index, TabVec2d));
0294 }
0295 
0296 //=======================================================================
0297 //function : MakeMLBetween
0298 //purpose  : 
0299 //=======================================================================
0300 ApproxInt_MultiLine
0301   ApproxInt_MultiLine::MakeMLBetween( const Standard_Integer Low,
0302                                       const Standard_Integer High,
0303                                       const Standard_Integer aNbPntsToInsert) const
0304 { 
0305   if(PtrOnmySvSurfaces==NULL) {
0306     //-- cout<<"\n Erreur dans : ApproxInt_MultiLine  ApproxInt_MultiLine::MakeMLBetween "<<endl;
0307     Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
0308     Handle(TheLine) vide = new TheLine(vide1,Standard_False);
0309     return (ApproxInt_MultiLine(vide,
0310                                 NULL,
0311                                 nbp3d,
0312                                 nbp2d,
0313                                 myApproxU1V1, myApproxU2V2,
0314                                 Xo,Yo,Zo,U1o,V1o,U2o,V2o,
0315                                 p2donfirst,
0316                                 1,1));
0317     //-- return(*this);
0318   }
0319 
0320   Standard_Boolean aSaveUseSolver = ((TheSvSurfaces *)PtrOnmySvSurfaces)->GetUseSolver();
0321   if (!aSaveUseSolver)
0322   {
0323     ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(Standard_True);
0324   }
0325   Standard_Integer NbPntsToInsert=aNbPntsToInsert;
0326   if(NbPntsToInsert<(High-Low)) NbPntsToInsert=(High-Low);
0327   Standard_Integer NbPnts = NbPntsToInsert + High - Low + 1;
0328   Standard_Integer NbPntsmin = High-Low;
0329   NbPntsmin+=NbPntsmin;
0330   
0331   if(NbPnts<NbPntsmin) NbPnts=NbPntsmin;
0332 
0333 
0334   gp_Vec T;
0335   gp_Vec2d TS1,TS2;
0336   gp_Pnt P;
0337   
0338   //-----------------------l-------------------------------------------
0339   //--  Indice     :   Low       Low+1     I    I+1         High    --
0340   //--                                                              --
0341   //--  Abs.Curv.  :  S(Low)              S(I)  S(I+1)      S(High) --
0342   //--                                                              --
0343   //--                On echantillonne a abcisse curviligne         --
0344   //--                constante.                                    --
0345   //--                L abcisse est calculee sur les params U1,V1   --
0346   //------------------------------------------------------------------
0347   TColStd_Array1OfReal U1(Low,High);
0348   TColStd_Array1OfReal V1(Low,High);
0349   TColStd_Array1OfReal U2(Low,High);
0350   TColStd_Array1OfReal V2(Low,High);
0351   TColStd_Array1OfReal AC(Low,High);
0352   Standard_Real s,ds;
0353   
0354   //------------------------------------------------------------
0355   //-- Creation des Tableaux U1 .. V2 et AC
0356   //-- 
0357   Standard_Real u1,v1,u2,v2;
0358   Standard_Integer i ;
0359   myLine->Point(Low).Parameters(u1,v1,u2,v2);
0360   U1(Low) = u1;
0361   V1(Low) = v1;
0362   U2(Low) = u2;
0363   V2(Low) = v2;
0364   AC(Low) =0.0;
0365   
0366 #if 0 
0367   for( i=Low+1; i<=High; i++) { 
0368     myLine->Point(i).Parameters(u1,v1,u2,v2);
0369     U1(i) = u1;
0370     V1(i) = v1;
0371     U2(i) = u2;
0372     V2(i) = v2;
0373     
0374     Standard_Real du1=u1-U1(i-1);
0375     Standard_Real dv1=v1-V1(i-1);
0376     
0377     AC(i) = AC(i-1) + sqrt((du1*du1)+(dv1*dv1));
0378   }
0379 #else 
0380   //-- Essai du 19 juin 96 (parametrage selon abs curv en XYZ)
0381   for( i=Low+1; i<=High; i++) { 
0382     myLine->Point(i).Parameters(u1,v1,u2,v2);
0383     U1(i) = u1;
0384     V1(i) = v1;
0385     U2(i) = u2;
0386     V2(i) = v2;    
0387     AC(i) = AC(i-1) + (myLine->Point(i-1).Value()).Distance(myLine->Point(i).Value());
0388   }
0389 
0390 #endif
0391   //-------------------------------------------------------------
0392   //-- Creation des structures contenant les resultats
0393   
0394   Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
0395   
0396   IntSurf_PntOn2S StartPOn2S;  
0397   TColStd_Array1OfReal StartParams(1,4);  
0398   
0399   ds = AC(High) / (NbPnts-1);
0400   Standard_Integer Indice = Low;
0401   Standard_Boolean HasBeenInserted = Standard_False;
0402   Standard_Real dsmin = ds*0.3;
0403   Standard_Real smax  = AC(High);
0404   
0405   for(i=2,s=ds; (s < smax && Indice <= High-1); i++,s+=ds) { 
0406     //----------------------------------------------------------
0407     //-- Recherche des indices des points                     --
0408     //-- Point           :    2       i       NbPnts-1        --
0409     //-- s                            s                       --
0410     //-- Current Indice tel que AC(Indice)<= s < AC(Indice+1) --
0411     //----------------------------------------------------------
0412     while(AC(Indice+1) <= s)
0413     { 
0414       if(!HasBeenInserted)
0415         ResultPntOn2SLine->Add(myLine->Point(Indice));
0416 
0417       HasBeenInserted = Standard_False;
0418       Indice++;
0419       if (Indice == High)
0420         break;
0421     }
0422     
0423     if (Indice == High)
0424       break;
0425     
0426     if(!HasBeenInserted  && AC(Indice) <= s)
0427     { 
0428       ResultPntOn2SLine->Add(myLine->Point(Indice));
0429       HasBeenInserted = Standard_True;
0430     }
0431     
0432     Standard_Real a = s - AC(Indice);
0433     Standard_Real b = AC(Indice+1) - s;
0434     Standard_Real nab = 1.0/(a+b);
0435     
0436     //----------------------------------------------------------
0437     //-- Verification :  Si Dist au prochain  point < dsmin   --
0438     //--                 Si Dist au precedent point < dsmin   --
0439     //--                                                      --
0440     //----------------------------------------------------------
0441     if((a>dsmin) && (b>dsmin))
0442     {
0443       u1 = (U1(Indice) * b   +  U1(Indice+1) * a) * nab;
0444       v1 = (V1(Indice) * b   +  V1(Indice+1) * a) * nab;
0445       u2 = (U2(Indice) * b   +  U2(Indice+1) * a) * nab;
0446       v2 = (V2(Indice) * b   +  V2(Indice+1) * a) * nab;
0447             
0448       if(((TheSvSurfaces *)PtrOnmySvSurfaces)->Compute(u1,v1,u2,v2,P,T,TS1,TS2))
0449       {
0450         StartPOn2S.SetValue(P,u1,v1,u2,v2);
0451         //-- cout<<" Insertion du point calcule : "<<u1<<","<<v1<<","<<u2<<","<<v2<<",";
0452         //-- cout<<P.X()<<","<<P.Y()<<","<<P.Z()<<endl;
0453         ResultPntOn2SLine->Add(StartPOn2S);
0454       }
0455       else
0456       {
0457         //-- cout<<" Probleme Non Traite ds ApproxInt_ApproxIntIntersection "<<endl;
0458       }
0459     }
0460     else
0461     {
0462       //-- Point non situe a distance suffisante de 2 pts existants
0463       //-- avec le point p[indice] deja insere
0464       
0465       if(b<0.0)
0466       {
0467         while(AC(Indice+1) <= s)
0468         {
0469           if(!HasBeenInserted)
0470             ResultPntOn2SLine->Add(myLine->Point(Indice));
0471 
0472           //-- cout<<" Insertion du point :"<<Indice<<endl;
0473           HasBeenInserted = Standard_False;
0474           Indice++;
0475 
0476           if (Indice == High)
0477             break;
0478         }
0479 
0480         if(Indice == High)
0481           break;
0482 
0483         if(!HasBeenInserted  && AC(Indice) <= s)
0484         {
0485           ResultPntOn2SLine->Add(myLine->Point(Indice));
0486           HasBeenInserted = Standard_True;
0487         }
0488       }
0489       else
0490       {
0491         s+= (dsmin - ds);
0492       }
0493     }
0494   }
0495   
0496   ResultPntOn2SLine->Add(myLine->Point(High));     //--  Point NbPnts
0497   Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
0498   
0499   //-- Verification   a posteriori 
0500   //-- On verifie qu il n y a pas de virage trop important en 2d et en 3d
0501   
0502   temp->Point(1).Parameters(u1,v1,u2,v2);
0503   gp_Pnt2d P1A(u1,v1);
0504   gp_Pnt2d P2A(u2,v2);
0505 
0506   temp->Point(2).Parameters(u1,v1,u2,v2);
0507   gp_Pnt2d P1B(u1,v1);
0508   gp_Pnt2d P2B(u2,v2);
0509 
0510   gp_Pnt2d P1C,P2C;
0511 
0512   Standard_Integer CodeErreur=0; 
0513   
0514   for(i=3,NbPnts=temp->NbPnts();CodeErreur==0 &&  i<=NbPnts; i++)
0515   {
0516     Standard_Real d,du,dv,duv2;
0517     temp->Point(i).Parameters(u1,v1,u2,v2);
0518     //-- Virage P1A P1B P1C
0519     P1C.SetCoord(u1,v1);
0520     du  = P1B.X()-P1A.X();
0521     dv  = P1B.Y()-P1A.Y();
0522     duv2= 0.25*(du*du+dv*dv);
0523     u1 = P1B.X() + du;
0524     v1 = P1B.Y() + dv;
0525     du = P1C.X() - u1;
0526     dv = P1C.Y() - v1;
0527     d = du*du+dv*dv;
0528     if(d>duv2)
0529     { 
0530       CodeErreur = 1;
0531       CodeErreur = 1;
0532       break;
0533     }
0534     
0535     //-- Virage P2A P2B P2C
0536     P2C.SetCoord(u2,v2);
0537     du  = P2B.X()-P2A.X();
0538     dv  = P2B.Y()-P2A.Y();
0539     duv2= 0.25*(du*du+dv*dv);
0540     u2 = P2B.X() + du;
0541     v2 = P2B.Y() + dv;
0542     du = P2C.X() - u2;
0543     dv = P2C.Y() - v2;
0544     d = du*du+dv*dv;
0545     if(d>duv2)
0546     {
0547       CodeErreur = 2;
0548       break;
0549     }
0550     
0551     P1A=P1B;
0552     P2A=P2B;
0553     P1B=P1C;
0554     P2B=P2C;
0555   }
0556 
0557 #ifdef OCCT_DEBUG
0558   //if (temp->NbPnts() < NbPntsToInsert + High - Low + 1)
0559   //{ 
0560   //  cout<<" *** Pas assez de points entre :"<<
0561   //            Low<<" et "<<High<<" -> "<<temp->NbPnts()<<endl;
0562   //}
0563 
0564   //if(CodeErreur)
0565   //{ 
0566   //  cout<<" *** CodeErreur : "<<CodeErreur<<endl;
0567   //}
0568 #endif
0569 
0570   if((temp->NbPnts() >= NbPntsToInsert + High - Low + 1) && (CodeErreur==0))
0571   {
0572     ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(aSaveUseSolver);
0573     return (ApproxInt_MultiLine( temp, 
0574                                  (High-Low>10)? PtrOnmySvSurfaces : NULL,
0575                                  nbp3d,
0576                                  nbp2d,
0577                                  myApproxU1V1, myApproxU2V2,
0578                                  Xo,Yo,Zo,
0579                                  U1o,V1o,
0580                                  U2o,V2o,
0581                                  p2donfirst,
0582                                  1,ResultPntOn2SLine->NbPoints()));
0583   }
0584   else
0585   {
0586     //-- cout<<" ApproxInt_MultiLine "<<endl;
0587     //-- cout<<" Pas de Rajout de points ds1min =  "<<minds1<<" ds2min = "<<minds2<<endl;
0588     ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(aSaveUseSolver);
0589     Handle(IntSurf_LineOn2S) vide1 = new IntSurf_LineOn2S();
0590     Handle(TheLine) vide = new TheLine(vide1,Standard_False);
0591     return (ApproxInt_MultiLine( vide,
0592                                  NULL,
0593                                  nbp3d,
0594                                  nbp2d,
0595                                  myApproxU1V1, myApproxU2V2,
0596                                  Xo,Yo,Zo,
0597                                  U1o,V1o,
0598                                 U2o,V2o,
0599                                  p2donfirst,
0600                                  1,1));
0601   }
0602 }
0603 
0604 //=======================================================================
0605 //function : MakeMLOneMorePoint
0606 //purpose  : 
0607 //=======================================================================
0608 Standard_Boolean
0609   ApproxInt_MultiLine::MakeMLOneMorePoint(const Standard_Integer theLow,
0610                                           const Standard_Integer theHigh,
0611                                           const Standard_Integer theIndbad,
0612                                           ApproxInt_MultiLine& theNewMultiLine) const
0613 {
0614   Standard_Boolean OtherLineMade = Standard_False;
0615   if(PtrOnmySvSurfaces==NULL)
0616     return Standard_False;
0617 
0618   Standard_Boolean aSaveUseSolver = ((TheSvSurfaces *)PtrOnmySvSurfaces)->GetUseSolver();
0619   if (!aSaveUseSolver)
0620   {
0621     ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(Standard_True);
0622   }
0623 
0624   const Standard_Real SqTol3d = Precision::SquareConfusion();
0625   math_Vector tolerance(1,2);
0626   tolerance(1) = tolerance(2) = 1.e-8;
0627   
0628   Handle(IntSurf_LineOn2S) ResultPntOn2SLine = new IntSurf_LineOn2S();
0629   for (Standard_Integer Indice = theLow; Indice <= theHigh; Indice++)
0630     ResultPntOn2SLine->Add(myLine->Point(Indice));
0631 
0632   //Insert new point between (theIndbad-1) and theIndbad
0633   //Using <thePtrSVSurf> for Rsnld: it may be ImpPrm or PrmPrm
0634   gp_Pnt PrevPnt = myLine->Point(theIndbad-1).Value();
0635   gp_Pnt CurPnt  = myLine->Point(theIndbad).Value();
0636   Standard_Real uprev1, vprev1, uprev2, vprev2, ucur1, vcur1, ucur2, vcur2;
0637   myLine->Point(theIndbad-1).Parameters(uprev1, vprev1, uprev2, vprev2);
0638   myLine->Point(theIndbad).Parameters(ucur1, vcur1, ucur2, vcur2);
0639   Standard_Real umid1, vmid1, umid2, vmid2;
0640   umid1 = (uprev1 + ucur1)/2;
0641   vmid1 = (vprev1 + vcur1)/2;
0642   umid2 = (uprev2 + ucur2)/2;
0643   vmid2 = (vprev2 + vcur2)/2;
0644   IntSurf_PntOn2S MidPoint;
0645   Standard_Boolean IsNewPointInvalid = Standard_False;
0646   IsNewPointInvalid =
0647     myApproxU1V1 &&
0648     Abs(ucur1 - umid1) <= tolerance(1) &&
0649     Abs(vcur1 - vmid1) <= tolerance(2);
0650   if (!IsNewPointInvalid)
0651   {
0652     IsNewPointInvalid =
0653       myApproxU2V2 &&
0654       Abs(ucur2 - umid2) <= tolerance(1) &&
0655       Abs(vcur2 - vmid2) <= tolerance(2);
0656     if (!IsNewPointInvalid &&
0657         ((TheSvSurfaces *)PtrOnmySvSurfaces)->SeekPoint(umid1, vmid1, umid2, vmid2,
0658                                                         MidPoint))
0659     {
0660       const gp_Pnt& NewPnt = MidPoint.Value();
0661       Standard_Real SqDistNewPrev = NewPnt.SquareDistance(PrevPnt);
0662       Standard_Real SqDistNewCur  = NewPnt.SquareDistance(CurPnt);
0663       IsNewPointInvalid = (SqDistNewPrev <= SqTol3d ||
0664                            SqDistNewCur  <= SqTol3d);
0665       if (!IsNewPointInvalid)
0666       {
0667         Standard_Real unew1, vnew1, unew2, vnew2;
0668         MidPoint.Parameters(unew1, vnew1, unew2, vnew2);
0669         if (myApproxU1V1)
0670         {
0671           Standard_Real SqDistCurMid1 =
0672             (ucur1 - umid1)*(ucur1 - umid1)+(vcur1 - vmid1)*(vcur1 - vmid1);
0673           Standard_Real SqDistMidNew1 =
0674             (umid1 - unew1)*(umid1 - unew1)+(vmid1 - vnew1)*(vmid1 - vnew1);
0675           IsNewPointInvalid = (SqDistMidNew1 > SqDistCurMid1);
0676         }
0677         if (!IsNewPointInvalid)
0678         {
0679           if (myApproxU2V2)
0680           {
0681             Standard_Real SqDistCurMid2 =
0682               (ucur2 - umid2)*(ucur2 - umid2)+(vcur2 - vmid2)*(vcur2 - vmid2);
0683             Standard_Real SqDistMidNew2 =
0684               (umid2 - unew2)*(umid2 - unew2)+(vmid2 - vnew2)*(vmid2 - vnew2);
0685             IsNewPointInvalid = (SqDistMidNew2 > SqDistCurMid2);
0686           }
0687           if (!IsNewPointInvalid)
0688           {
0689             ResultPntOn2SLine->InsertBefore(theIndbad-theLow+1, MidPoint);
0690             OtherLineMade = Standard_True;
0691           }
0692         }
0693       }
0694     }
0695   }
0696 
0697   if (!OtherLineMade)
0698   {
0699     ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(aSaveUseSolver);
0700     return Standard_False;
0701   }
0702 
0703 #ifdef DRAW
0704   char* name = new char[100];
0705   Standard_Integer indc = 1;
0706   Standard_Boolean onfirst = Standard_True;
0707   for (Standard_Integer i = 1; i <= ResultPntOn2SLine->NbPoints(); i++)
0708   {
0709     const IntSurf_PntOn2S& thePoint = ResultPntOn2SLine->Value(i);
0710     gp_Pnt curPnt = thePoint.Value();
0711     sprintf(name, "p%d_%d", indc, i);
0712     DrawTrSurf::Set(name, curPnt);
0713     gp_Pnt2d curPnt2d = thePoint.ValueOnSurface(onfirst);
0714     sprintf(name, "pp%d_%d", indc, i);
0715     DrawTrSurf::Set(name, curPnt2d);
0716   }
0717 #endif
0718   Handle(TheLine) temp = new TheLine(ResultPntOn2SLine,Standard_False);
0719   ((TheSvSurfaces *)PtrOnmySvSurfaces)->SetUseSolver(aSaveUseSolver);
0720   theNewMultiLine = ApproxInt_MultiLine( temp, 
0721                                          PtrOnmySvSurfaces,
0722                                          nbp3d,
0723                                          nbp2d,
0724                                          myApproxU1V1,
0725                                          myApproxU2V2,
0726                                          Xo,Yo,Zo,
0727                                          U1o,V1o,
0728                                          U2o,V2o,
0729                                          p2donfirst,
0730                                          1,ResultPntOn2SLine->NbPoints());
0731   return Standard_True;
0732 }
0733 
0734 //=======================================================================
0735 //function : Dump
0736 //purpose  : 
0737 //=======================================================================
0738 void ApproxInt_MultiLine::Dump() const
0739 {
0740   TColgp_Array1OfPnt anArr1(1, 1);
0741   TColgp_Array1OfPnt2d anArr2(1, 2);
0742         
0743   const Standard_Integer  anIndF = FirstPoint(),
0744                           anIndL = LastPoint();
0745         
0746   for(Standard_Integer ind = anIndF; ind <= anIndL; ind++)
0747   {
0748     Value(ind, anArr1, anArr2);
0749     printf("%4d  [%+10.20f %+10.20f %+10.20f]  "
0750             "[%+10.20f %+10.20f]  [%+10.20f %+10.20f]\n",
0751       ind, anArr1(1).X(), anArr1(1).Y(), anArr1(1).Z(), anArr2(1).X(),
0752       anArr2(1).Y(),anArr2(2).X(),anArr2(2).Y());
0753   }
0754 }
0755