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 }