Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // Created on: 1993-03-30
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 <AppParCurves_Constraint.hxx>
0018 #include <GeomAbs_SurfaceType.hxx>
0019 #include <IntSurf_Quadric.hxx>
0020 #include <gp_Trsf.hxx>
0021 #include <gp_Trsf2d.hxx>
0022 #include <IntSurf_PntOn2S.hxx>
0023 #include <Precision.hxx>
0024 #include <ApproxInt_KnotTools.hxx>
0025 
0026 // If quantity of points is less than aMinNbPointsForApprox
0027 // then interpolation is used.
0028 const Standard_Integer aMinNbPointsForApprox = 5;
0029 
0030 // This constant should be removed in the future.
0031 const Standard_Real RatioTol = 1.5 ;
0032 
0033 //=======================================================================
0034 //function : ComputeTrsf3d
0035 //purpose  : 
0036 //=======================================================================
0037 static void ComputeTrsf3d(const Handle(TheWLine)& theline,
0038                           Standard_Real& theXo,
0039                           Standard_Real& theYo,
0040                           Standard_Real& theZo)
0041 {
0042   const Standard_Integer aNbPnts = theline->NbPnts();
0043   Standard_Real aXmin = RealLast(), aYmin = RealLast(), aZmin = RealLast();
0044   for(Standard_Integer i=1;i<=aNbPnts;i++)
0045   {
0046     const gp_Pnt P = theline->Point(i).Value();
0047     aXmin = Min(P.X(), aXmin);
0048     aYmin = Min(P.Y(), aYmin);
0049     aZmin = Min(P.Z(), aZmin);
0050   }
0051 
0052   theXo = -aXmin;
0053   theYo = -aYmin;
0054   theZo = -aZmin;
0055 }
0056 
0057 //=======================================================================
0058 //function : ComputeTrsf2d
0059 //purpose  : 
0060 //=======================================================================
0061 static void ComputeTrsf2d(const Handle(TheWLine)& theline,
0062                           const Standard_Boolean onFirst,
0063                           Standard_Real& theUo,
0064                           Standard_Real& theVo)
0065 { 
0066   const Standard_Integer aNbPnts = theline->NbPnts();
0067   Standard_Real aUmin = RealLast(), aVmin = RealLast();
0068 
0069   // pointer to a member-function
0070   void (IntSurf_PntOn2S::* pfunc)(Standard_Real&,Standard_Real&) const;
0071 
0072   if (onFirst)
0073     pfunc = &IntSurf_PntOn2S::ParametersOnS1;
0074   else
0075     pfunc = &IntSurf_PntOn2S::ParametersOnS2;
0076   
0077   for(Standard_Integer i=1; i<=aNbPnts; i++)
0078   {
0079     const IntSurf_PntOn2S POn2S = theline->Point(i);
0080     Standard_Real  U,V;
0081     (POn2S.*pfunc)(U,V);
0082     aUmin = Min(U, aUmin);
0083     aVmin = Min(V, aVmin);
0084   }
0085 
0086   theUo = -aUmin;
0087   theVo = -aVmin;
0088 }
0089 
0090 //=======================================================================
0091 //function : Parameters
0092 //purpose  :
0093 //=======================================================================
0094 void ApproxInt_Approx::Parameters(const ApproxInt_TheMultiLine& Line,
0095                        const Standard_Integer firstP,
0096                        const Standard_Integer lastP,
0097                        const Approx_ParametrizationType Par,
0098                        math_Vector& TheParameters)
0099 {
0100   Standard_Integer i, j, nbP2d, nbP3d;
0101   Standard_Real dist;
0102 
0103   if (Par == Approx_ChordLength || Par == Approx_Centripetal) {
0104     nbP3d = ApproxInt_TheMultiLineTool::NbP3d(Line);
0105     nbP2d = ApproxInt_TheMultiLineTool::NbP2d(Line);
0106     Standard_Integer mynbP3d=nbP3d, mynbP2d=nbP2d;
0107     if (nbP3d == 0) mynbP3d = 1;
0108     if (nbP2d == 0) mynbP2d = 1;
0109 
0110     TheParameters(firstP) = 0.0;
0111     dist = 0.0;
0112     TColgp_Array1OfPnt tabP(1, mynbP3d);
0113     TColgp_Array1OfPnt tabPP(1, mynbP3d);
0114     TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
0115     TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d);
0116 
0117     for (i = firstP+1; i <= lastP; i++) {
0118       if (nbP3d != 0 && nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP, tabP2d);
0119       else if (nbP2d != 0)          ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP2d);
0120       else if (nbP3d != 0)          ApproxInt_TheMultiLineTool::Value(Line, i-1, tabP);
0121 
0122       if (nbP3d != 0 && nbP2d != 0) ApproxInt_TheMultiLineTool::Value(Line, i, tabPP, tabPP2d);
0123       else if (nbP2d != 0)          ApproxInt_TheMultiLineTool::Value(Line, i, tabPP2d);
0124       else if (nbP3d != 0)          ApproxInt_TheMultiLineTool::Value(Line, i, tabPP);
0125       dist = 0;
0126       for (j = 1; j <= nbP3d; j++) {
0127         const gp_Pnt &aP1 = tabP(j),
0128                      &aP2 = tabPP(j);
0129         dist += aP2.SquareDistance(aP1);
0130       }
0131       for (j = 1; j <= nbP2d; j++) {
0132         const gp_Pnt2d &aP12d = tabP2d(j),
0133                        &aP22d = tabPP2d(j);
0134 
0135         dist += aP22d.SquareDistance(aP12d);
0136       }
0137 
0138       dist = Sqrt(dist);
0139       if(Par == Approx_ChordLength)
0140       {
0141         TheParameters(i) = TheParameters(i - 1) + dist;
0142       }
0143       else
0144       {// Par == Approx_Centripetal
0145         TheParameters(i) = TheParameters(i - 1) + Sqrt(dist);
0146       }
0147     }
0148     for (i = firstP; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
0149   }
0150   else {
0151     for (i = firstP; i <= lastP; i++) {
0152       TheParameters(i) = (Standard_Real(i)-firstP)/
0153         (Standard_Real(lastP)-Standard_Real(firstP));
0154     }
0155   }
0156 }
0157 
0158 //=======================================================================
0159 //function : Default constructor
0160 //purpose  : 
0161 //=======================================================================
0162 ApproxInt_Approx::ApproxInt_Approx():
0163                       myComputeLine(4, 8, 0.001, 0.001, 5),
0164                       myComputeLineBezier(4, 8, 0.001, 0.001, 5),
0165                       myWithTangency(Standard_True),
0166                       myTol3d(0.001),
0167                       myTol2d(0.001),
0168                       myDegMin(4),
0169                       myDegMax(8),
0170                       myNbIterMax(5),
0171                       myTolReached3d(0.0),
0172                       myTolReached2d(0.0)
0173 {
0174   myComputeLine.SetContinuity(2);
0175   //myComputeLineBezier.SetContinuity(2);
0176 }
0177 
0178 //=======================================================================
0179 //function : Perform
0180 //purpose  : Build without surfaces information.
0181 //=======================================================================
0182 void ApproxInt_Approx::Perform(const Handle(TheWLine)& theline,
0183                                const Standard_Boolean ApproxXYZ,
0184                                const Standard_Boolean ApproxU1V1,
0185                                const Standard_Boolean ApproxU2V2,
0186                                const Standard_Integer indicemin,
0187                                const Standard_Integer indicemax)
0188 {
0189   // Prepare DS.
0190   prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
0191 
0192   const Standard_Integer nbpntbez = myData.indicemax - myData.indicemin;
0193   if(nbpntbez < aMinNbPointsForApprox) 
0194     myData.myBezierApprox = Standard_False;
0195   else 
0196     myData.myBezierApprox = Standard_True;
0197 
0198   // Fill data structure.
0199   fillData(theline);
0200 
0201   // Build knots.
0202   buildKnots(theline, NULL);
0203   if (myKnots.Length() == 2 &&
0204       indicemax - indicemin > 2 * myData.myNbPntMax)
0205   {
0206     // At least 3 knots for BrepApprox.
0207     myKnots.ChangeLast() = (indicemax - indicemin) / 2;
0208     myKnots.Append(indicemax);
0209   }
0210 
0211   myComputeLine.Init      (myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization);
0212   myComputeLineBezier.Init(myDegMin, myDegMax, myTol3d, myTol2d, myNbIterMax, Standard_True, myData.parametrization);
0213 
0214   buildCurve(theline, NULL);
0215 }
0216 
0217 //=======================================================================
0218 //function : Perform
0219 //purpose  : Definition of next steps according to surface types
0220 //            (i.e. coordination algorithm).
0221 //=======================================================================
0222 void ApproxInt_Approx::Perform(const ThePSurface& Surf1,
0223                                const ThePSurface& Surf2,
0224                                const Handle(TheWLine)& theline,
0225                                const Standard_Boolean ApproxXYZ,
0226                                const Standard_Boolean ApproxU1V1,
0227                                const Standard_Boolean ApproxU2V2,
0228                                const Standard_Integer indicemin,
0229                                const Standard_Integer indicemax) 
0230 {
0231 
0232   myTolReached3d = myTolReached2d = 0.;
0233 
0234   const GeomAbs_SurfaceType typeS1 = ThePSurfaceTool::GetType(Surf1);
0235   const GeomAbs_SurfaceType typeS2 = ThePSurfaceTool::GetType(Surf2);
0236 
0237   const Standard_Boolean isQuadric = ((typeS1 == GeomAbs_Plane) ||
0238                                       (typeS1 == GeomAbs_Cylinder) ||
0239                                       (typeS1 == GeomAbs_Sphere) ||
0240                                       (typeS1 == GeomAbs_Cone) ||
0241                                       (typeS2 == GeomAbs_Plane) ||
0242                                       (typeS2 == GeomAbs_Cylinder) ||
0243                                       (typeS2 == GeomAbs_Sphere) ||
0244                                       (typeS2 == GeomAbs_Cone));
0245 
0246   if(isQuadric)
0247   {
0248     IntSurf_Quadric Quad;
0249     Standard_Boolean SecondIsImplicit=Standard_False;
0250     switch (typeS1)
0251     {
0252     case GeomAbs_Plane:
0253       Quad.SetValue(ThePSurfaceTool::Plane(Surf1));
0254       break;
0255 
0256     case GeomAbs_Cylinder:
0257       Quad.SetValue(ThePSurfaceTool::Cylinder(Surf1));
0258       break;
0259 
0260     case GeomAbs_Sphere:
0261       Quad.SetValue(ThePSurfaceTool::Sphere(Surf1));
0262       break;
0263 
0264     case GeomAbs_Cone:
0265       Quad.SetValue(ThePSurfaceTool::Cone(Surf1));
0266       break;
0267 
0268     default:
0269       {
0270         SecondIsImplicit = Standard_True;
0271         switch (typeS2)
0272         {
0273         case GeomAbs_Plane:
0274           Quad.SetValue(ThePSurfaceTool::Plane(Surf2));
0275           break;
0276 
0277         case GeomAbs_Cylinder:
0278           Quad.SetValue(ThePSurfaceTool::Cylinder(Surf2));
0279           break;
0280 
0281         case GeomAbs_Sphere:
0282           Quad.SetValue(ThePSurfaceTool::Sphere(Surf2));
0283           break;
0284 
0285         case GeomAbs_Cone:
0286           Quad.SetValue(ThePSurfaceTool::Cone(Surf2));
0287           break;
0288 
0289         default:
0290           break;
0291         }//switch (typeS2)
0292       }
0293 
0294       break;
0295     }//switch (typeS1)
0296 
0297     Perform(Quad, (SecondIsImplicit? Surf1: Surf2), theline,
0298             ApproxXYZ, ApproxU1V1, ApproxU2V2,
0299             indicemin, indicemax, !SecondIsImplicit);
0300 
0301     return;
0302   }
0303 
0304   // Here, isQuadric == FALSE.
0305 
0306   // Prepare DS.
0307   prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
0308 
0309   // Non-analytical case: Param-Param perform.
0310   ApproxInt_ThePrmPrmSvSurfaces myPrmPrmSvSurfaces(Surf1,Surf2);
0311 
0312   Standard_Integer nbpntbez = indicemax-indicemin;
0313 
0314   if(nbpntbez < aMinNbPointsForApprox)
0315   {
0316     myData.myBezierApprox = Standard_False;
0317   }
0318   else 
0319   {
0320     myData.myBezierApprox = Standard_True;
0321   }
0322 
0323   // Fill data structure.
0324   fillData(theline);
0325 
0326   const Standard_Boolean cut = myData.myBezierApprox;
0327   const Standard_Address ptrsvsurf = &myPrmPrmSvSurfaces;
0328 
0329   // Build knots.
0330   buildKnots(theline, ptrsvsurf);
0331 
0332   myComputeLine.Init      ( myDegMin, myDegMax, myTol3d, myTol2d,
0333                             myNbIterMax, cut, myData.parametrization);
0334   myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d,
0335                             myNbIterMax, cut, myData.parametrization);
0336 
0337   buildCurve(theline, ptrsvsurf);
0338 }
0339 
0340 //=======================================================================
0341 //function : Perform
0342 //purpose  : Analytic-Param perform.
0343 //=======================================================================
0344 void ApproxInt_Approx::Perform(const TheISurface& ISurf,
0345                                const ThePSurface& PSurf,
0346                                const Handle(TheWLine)& theline,
0347                                const Standard_Boolean ApproxXYZ,
0348                                const Standard_Boolean ApproxU1V1,
0349                                const Standard_Boolean ApproxU2V2,
0350                                const Standard_Integer indicemin,
0351                                const Standard_Integer indicemax,
0352                                const Standard_Boolean isTheQuadFirst)
0353 {
0354   // Prepare DS.
0355   prepareDS(ApproxXYZ, ApproxU1V1, ApproxU2V2, indicemin, indicemax);
0356 
0357   // Non-analytical case: Analytic-Param perform.
0358   ApproxInt_TheImpPrmSvSurfaces myImpPrmSvSurfaces = 
0359                           isTheQuadFirst? ApproxInt_TheImpPrmSvSurfaces(ISurf, PSurf):
0360                                           ApproxInt_TheImpPrmSvSurfaces(PSurf, ISurf);
0361 
0362   myImpPrmSvSurfaces.SetUseSolver(Standard_False);
0363 
0364   const Standard_Integer nbpntbez = indicemax-indicemin;
0365   if(nbpntbez < aMinNbPointsForApprox)
0366   {
0367     myData.myBezierApprox = Standard_False;
0368   }
0369   else 
0370   {
0371     myData.myBezierApprox = Standard_True;
0372   }
0373 
0374   const Standard_Boolean cut = myData.myBezierApprox;
0375   const Standard_Address ptrsvsurf = &myImpPrmSvSurfaces;
0376 
0377   // Fill data structure.
0378   fillData(theline);
0379 
0380   // Build knots.
0381   buildKnots(theline, ptrsvsurf);
0382 
0383   myComputeLine.Init      ( myDegMin, myDegMax, myTol3d, myTol2d,
0384                             myNbIterMax, cut, myData.parametrization);
0385   myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d,
0386                             myNbIterMax, cut, myData.parametrization);
0387 
0388   buildCurve(theline, ptrsvsurf);
0389 }
0390 
0391 //=======================================================================
0392 //function : SetParameters
0393 //purpose  : 
0394 //=======================================================================
0395 void ApproxInt_Approx::SetParameters( const Standard_Real Tol3d,
0396                                       const Standard_Real Tol2d,
0397                                       const Standard_Integer DegMin,
0398                                       const Standard_Integer DegMax,
0399                                       const Standard_Integer NbIterMax,
0400                                       const Standard_Integer NbPntMax,
0401                                       const Standard_Boolean ApproxWithTangency,
0402                                       const Approx_ParametrizationType Parametrization)
0403 {
0404   myData.myNbPntMax = NbPntMax;
0405   myWithTangency = ApproxWithTangency;
0406   myTol3d        = Tol3d/RatioTol;
0407   myTol2d        = Tol2d/RatioTol;
0408   myDegMin       = DegMin;
0409   myDegMax       = DegMax;
0410   myNbIterMax    = NbIterMax;
0411 
0412   myComputeLine.Init      ( myDegMin, myDegMax, myTol3d, myTol2d,
0413                             myNbIterMax, Standard_True, Parametrization);
0414   myComputeLineBezier.Init( myDegMin, myDegMax, myTol3d, myTol2d,
0415                             myNbIterMax, Standard_True, Parametrization);
0416 
0417   if(!ApproxWithTangency)
0418   { 
0419     myComputeLine.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
0420     myComputeLineBezier.SetConstraints(AppParCurves_PassPoint,AppParCurves_PassPoint);
0421   }
0422   
0423   myData.myBezierApprox = Standard_True;
0424 }
0425 
0426 //=======================================================================
0427 //function : NbMultiCurves
0428 //purpose  :
0429 //=======================================================================
0430 Standard_Integer ApproxInt_Approx::NbMultiCurves() const
0431 {
0432   return 1;
0433 }
0434 
0435 //=======================================================================
0436 //function : UpdateTolReached
0437 //purpose  :
0438 //=======================================================================
0439 void ApproxInt_Approx::UpdateTolReached()
0440 {
0441   if (myData.myBezierApprox)
0442   {
0443     const Standard_Integer NbCurves = myComputeLineBezier.NbMultiCurves() ;
0444     for (Standard_Integer ICur = 1 ; ICur <= NbCurves ; ICur++)
0445     {
0446       Standard_Real Tol3D, Tol2D ;
0447       myComputeLineBezier.Error (ICur, Tol3D, Tol2D) ;
0448       myTolReached3d = Max(myTolReached3d, Tol3D);
0449       myTolReached2d = Max(myTolReached2d, Tol2D);
0450     }
0451   }
0452   else
0453   {
0454     myComputeLine.Error (myTolReached3d, myTolReached2d);
0455   }
0456 }
0457 
0458 //=======================================================================
0459 //function : TolReached3d
0460 //purpose  :
0461 //=======================================================================
0462 Standard_Real ApproxInt_Approx::TolReached3d() const
0463 {
0464   return myTolReached3d * RatioTol;
0465 }
0466 
0467 //=======================================================================
0468 //function : TolReached2d
0469 //purpose  :
0470 //=======================================================================
0471 Standard_Real ApproxInt_Approx::TolReached2d() const
0472 {
0473   return myTolReached2d * RatioTol;
0474 }
0475 
0476 //=======================================================================
0477 //function : IsDone
0478 //purpose  :
0479 //=======================================================================
0480 Standard_Boolean ApproxInt_Approx::IsDone() const
0481 {
0482   if(myData.myBezierApprox)
0483   { 
0484     return(myComputeLineBezier.NbMultiCurves() > 0);
0485   }
0486   else
0487   {
0488     return(myComputeLine.IsToleranceReached());
0489   }
0490 }
0491 
0492 //=======================================================================
0493 //function : Value
0494 //purpose  :
0495 //=======================================================================
0496 const AppParCurves_MultiBSpCurve& ApproxInt_Approx::Value(const Standard_Integer ) const
0497 {
0498   if(myData.myBezierApprox)
0499   { 
0500     return(myBezToBSpl.Value());
0501   }
0502   else
0503   { 
0504     return(myComputeLine.Value());
0505   }
0506 }
0507 
0508 //=======================================================================
0509 //function : fillData
0510 //purpose  : Fill ApproxInt data structure.
0511 //=======================================================================
0512 void ApproxInt_Approx::fillData(const Handle(TheWLine)& theline)
0513 {
0514   if(myData.ApproxXYZ)
0515     ComputeTrsf3d(theline, myData.Xo, myData.Yo, myData.Zo);
0516   else
0517     myData.Xo = myData.Yo = myData.Zo = 0.0;
0518 
0519   if(myData.ApproxU1V1)
0520     ComputeTrsf2d(theline, Standard_True, myData.U1o, myData.V1o);
0521   else
0522     myData.U1o = myData.V1o = 0.0;
0523 
0524   if(myData.ApproxU2V2)
0525     ComputeTrsf2d(theline, Standard_False, myData.U2o, myData.V2o);
0526   else
0527     myData.U2o = myData.V2o = 0.0;
0528 }
0529 
0530 //=======================================================================
0531 //function : prepareDS
0532 //purpose  :
0533 //=======================================================================
0534 void ApproxInt_Approx::prepareDS(const Standard_Boolean theApproxXYZ,
0535                                  const Standard_Boolean theApproxU1V1,
0536                                  const Standard_Boolean theApproxU2V2,
0537                                  const Standard_Integer theIndicemin,
0538                                  const Standard_Integer theIndicemax)
0539 {
0540   myTolReached3d = myTolReached2d = 0.0;
0541   myData.ApproxU1V1 = theApproxU1V1;
0542   myData.ApproxU2V2 = theApproxU2V2;
0543   myData.ApproxXYZ = theApproxXYZ;
0544   myData.indicemin = theIndicemin;
0545   myData.indicemax = theIndicemax;
0546   myData.parametrization = myComputeLineBezier.Parametrization();
0547 }
0548 
0549 //=======================================================================
0550 //function : buildKnots
0551 //purpose  :
0552 //=======================================================================
0553 void ApproxInt_Approx::buildKnots(const Handle(TheWLine)& theline,
0554                                   const Standard_Address thePtrSVSurf)
0555 {
0556   myKnots.Clear();
0557   if(!myData.myBezierApprox)
0558   {
0559     myKnots.Append(myData.indicemin);
0560     myKnots.Append(myData.indicemax);
0561     return;
0562   }
0563 
0564   const ApproxInt_TheMultiLine aTestLine( theline, thePtrSVSurf,
0565                                           ((myData.ApproxXYZ)? 1 : 0),
0566                                           ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
0567                                           myData.ApproxU1V1, myData.ApproxU2V2,
0568                                           myData.Xo, myData.Yo, myData.Zo,
0569                                           myData.U1o, myData.V1o, myData.U2o, myData.V2o,
0570                                           myData.ApproxU1V1,
0571                                           myData.indicemin, myData.indicemax);
0572 
0573   const Standard_Integer  nbp3d = aTestLine.NbP3d(),
0574                           nbp2d = aTestLine.NbP2d();
0575   TColgp_Array1OfPnt aTabPnt3d(1, Max(1, nbp3d));
0576   TColgp_Array1OfPnt2d aTabPnt2d(1, Max(1, nbp2d));
0577   TColgp_Array1OfPnt aPntXYZ(myData.indicemin, myData.indicemax);
0578   TColgp_Array1OfPnt2d aPntU1V1(myData.indicemin, myData.indicemax);
0579   TColgp_Array1OfPnt2d aPntU2V2(myData.indicemin, myData.indicemax);
0580 
0581   for(Standard_Integer i = myData.indicemin; i <= myData.indicemax; ++i)
0582   {
0583     if (nbp3d != 0 && nbp2d != 0) aTestLine.Value(i, aTabPnt3d, aTabPnt2d);
0584     else if (nbp2d != 0)          aTestLine.Value(i, aTabPnt2d);
0585     else if (nbp3d != 0)          aTestLine.Value(i, aTabPnt3d);
0586     //
0587     if(nbp3d > 0)
0588     {
0589       aPntXYZ(i) = aTabPnt3d(1);
0590     }
0591     if(nbp2d > 1)
0592     {
0593       aPntU1V1(i) = aTabPnt2d(1);
0594       aPntU2V2(i) = aTabPnt2d(2);
0595     }
0596     else if(nbp2d > 0)
0597     {
0598       if(myData.ApproxU1V1)
0599       {
0600         aPntU1V1(i) = aTabPnt2d(1);
0601       }
0602       else
0603       {
0604         aPntU2V2(i) = aTabPnt2d(1);
0605       }
0606     }
0607   }
0608 
0609   Standard_Integer aMinNbPnts = myData.myNbPntMax;
0610 
0611   // Expected parametrization.
0612   math_Vector aPars(myData.indicemin, myData.indicemax);
0613   Parameters(aTestLine, myData.indicemin, myData.indicemax, myData.parametrization, aPars);
0614 
0615   ApproxInt_KnotTools::BuildKnots(aPntXYZ, aPntU1V1, aPntU2V2, aPars,
0616     myData.ApproxXYZ, myData.ApproxU1V1, myData.ApproxU2V2, aMinNbPnts, myKnots);
0617 }
0618 
0619 //=======================================================================
0620 //function : buildCurve
0621 //purpose  :
0622 //=======================================================================
0623 void ApproxInt_Approx::buildCurve(const Handle(TheWLine)& theline,
0624                                   const Standard_Address thePtrSVSurf)
0625 {
0626   if(myData.myBezierApprox)
0627   {
0628     myBezToBSpl.Reset();
0629   }
0630 
0631   Standard_Integer kind = myKnots.Lower();
0632   Standard_Integer imin = 0, imax = 0;
0633   Standard_Boolean OtherInter = Standard_False;
0634   do
0635   {
0636     // Base cycle: iterate over knots.
0637     imin = myKnots(kind);
0638     imax = myKnots(kind+1);
0639     ApproxInt_TheMultiLine myMultiLine(theline, thePtrSVSurf,
0640                                        ((myData.ApproxXYZ)? 1 : 0),
0641                                        ((myData.ApproxU1V1)? 1: 0) + ((myData.ApproxU2V2)? 1: 0),
0642                                        myData.ApproxU1V1, myData.ApproxU2V2,
0643                                        myData.Xo, myData.Yo, myData.Zo, myData.U1o, myData.V1o,
0644                                        myData.U2o, myData.V2o, myData.ApproxU1V1, imin, imax);
0645 
0646     if(myData.myBezierApprox)
0647     {
0648       myComputeLineBezier.Perform(myMultiLine);
0649       if (myComputeLineBezier.NbMultiCurves() == 0)
0650         return;
0651     }
0652     else
0653     {
0654       myComputeLine.Perform(myMultiLine);
0655     }
0656 
0657     UpdateTolReached();
0658 
0659     Standard_Integer indice3d = 1, indice2d1 = 2, indice2d2 = 3;
0660     if(!myData.ApproxXYZ)  { indice2d1--; indice2d2--; } 
0661     if(!myData.ApproxU1V1) { indice2d2--; } 
0662     if(myData.ApproxXYZ)
0663     { 
0664       if(myData.myBezierApprox)
0665       {
0666         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
0667         {
0668           myComputeLineBezier.ChangeValue(nbmc).Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0);
0669         }
0670       }
0671       else
0672       {
0673         myComputeLine.ChangeValue().Transform(indice3d, -myData.Xo, 1.0, -myData.Yo, 1.0, -myData.Zo, 1.0);
0674       }
0675     }
0676     if(myData.ApproxU1V1)
0677     {
0678       if(myData.myBezierApprox) {
0679         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
0680         {
0681           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0);
0682         }
0683       }
0684       else
0685       {
0686         myComputeLine.ChangeValue().Transform2d(indice2d1, -myData.U1o, 1.0, -myData.V1o, 1.0);
0687       }
0688     }
0689     if(myData.ApproxU2V2)
0690     {
0691       if(myData.myBezierApprox)
0692       {
0693         for(Standard_Integer nbmc = myComputeLineBezier.NbMultiCurves() ; nbmc>=1; nbmc--)
0694         {
0695           myComputeLineBezier.ChangeValue(nbmc).Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0);
0696         }
0697       }
0698       else
0699       {
0700         myComputeLine.ChangeValue().Transform2d(indice2d2, -myData.U2o, 1.0, -myData.V2o, 1.0);
0701       }
0702     }
0703 
0704     OtherInter = Standard_False;
0705     if(myData.myBezierApprox)
0706     {
0707       for(Standard_Integer nbmc = 1; 
0708         nbmc <= myComputeLineBezier.NbMultiCurves();
0709         nbmc++)
0710       {
0711           myBezToBSpl.Append(myComputeLineBezier.Value(nbmc));
0712       }
0713       kind++;
0714       if(kind < myKnots.Upper())
0715       {
0716         OtherInter = Standard_True;
0717       }
0718     }
0719   }
0720   while(OtherInter);
0721 
0722   if(myData.myBezierApprox)
0723   {
0724     myBezToBSpl.Perform();
0725   }
0726 }