Warning, /include/opencascade/Approx_BSplComputeLine.gxx is written in an unsupported language. File is not indexed.
0001 // Copyright (c) 1995-1999 Matra Datavision
0002 // Copyright (c) 1999-2014 OPEN CASCADE SAS
0003 //
0004 // This file is part of Open CASCADE Technology software library.
0005 //
0006 // This library is free software; you can redistribute it and/or modify it under
0007 // the terms of the GNU Lesser General Public License version 2.1 as published
0008 // by the Free Software Foundation, with special exception defined in the file
0009 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
0010 // distribution for complete text of the license and disclaimer of any warranty.
0011 //
0012 // Alternatively, this file may be used under the terms of Open CASCADE
0013 // commercial license or contractual agreement.
0014
0015 #include <stdio.h>
0016
0017 #include <Approx_ParametrizationType.hxx>
0018 #include <TColStd_Array1OfReal.hxx>
0019 #include <TColgp_Array1OfPnt.hxx>
0020 #include <TColgp_Array1OfPnt2d.hxx>
0021 #include <gp_Pnt.hxx>
0022 #include <gp_Pnt2d.hxx>
0023 #include <gp_Vec.hxx>
0024 #include <gp_Vec2d.hxx>
0025 #include <TColgp_Array1OfVec.hxx>
0026 #include <TColgp_Array1OfVec2d.hxx>
0027 #include <AppParCurves_Constraint.hxx>
0028 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
0029 #include <AppParCurves_MultiPoint.hxx>
0030 #include <Precision.hxx>
0031 #include <math_IntegerVector.hxx>
0032 #include <math_Gauss.hxx>
0033 #include <math_Uzawa.hxx>
0034 #include <AppParCurves_ConstraintCouple.hxx>
0035 #include Approx_BSpParLeastSquareOfMyBSplGradient_hxx
0036
0037 #if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
0038
0039 static Standard_Boolean mydebug = Standard_False;
0040
0041 #include <Draw.hxx>
0042 #include <Draw_Appli.hxx>
0043 #include <DrawTrSurf.hxx>
0044 #include <Draw_Text2D.hxx>
0045 #include <Draw_Text3D.hxx>
0046 #include <TColStd_Array1OfInteger.hxx>
0047 #include <Geom_BSplineCurve.hxx>
0048 #include <Geom2d_BSplineCurve.hxx>
0049 #include <Geom_Line.hxx>
0050 #include <Geom2d_Line.hxx>
0051 #include <Geom_TrimmedCurve.hxx>
0052 #include <Geom2d_TrimmedCurve.hxx>
0053
0054
0055 static void DUMP(const MultiLine& Line)
0056 {
0057 Standard_Integer i, j, nbP2d, nbP3d, firstP, lastP;
0058 firstP = LineTool::FirstPoint(Line);
0059 lastP = LineTool::LastPoint(Line);
0060
0061 nbP3d = LineTool::NbP3d(Line);
0062 nbP2d = LineTool::NbP2d(Line);
0063 Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0064 if (nbP3d == 0) mynbP3d = 1;
0065 if (nbP2d == 0) mynbP2d = 1;
0066
0067 TColgp_Array1OfPnt tabP(1, mynbP3d);
0068 TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
0069 TColgp_Array1OfVec TabV(1, mynbP3d);
0070 TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
0071 Standard_Boolean Ok;
0072 Handle(Geom_Line) L3d;
0073 Handle(Geom2d_Line) L2d;
0074 Handle(Geom_TrimmedCurve) L3dt;
0075 Handle(Geom2d_TrimmedCurve) L2dt;
0076 Handle(Draw_Text2D) T2D;
0077 Handle(Draw_Text3D) T3D;
0078
0079 char solname[100];
0080 char mytext[10];
0081
0082 for (i = firstP; i <= lastP; i++) {
0083 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabP, tabP2d);
0084 else if (nbP2d != 0) LineTool::Value(Line, i, tabP2d);
0085 else if (nbP3d != 0) LineTool::Value(Line, i, tabP);
0086
0087 for (j = 1; j <= nbP3d; j++) {
0088 sprintf(solname, "%s%i%s_%i", "p", j, "3d", i);
0089 char* Temp = solname;
0090 DrawTrSurf::Set(Temp, tabP(j));
0091 // DrawTrSurf::Set(solname, tabP(j));
0092 if (i == firstP || i == lastP) {
0093 sprintf(mytext, "%s%i", " ", i);
0094 T3D = new Draw_Text3D(tabP(j), mytext, Draw_vert);
0095 dout << T3D;
0096 }
0097 }
0098 for (j = 1; j <= nbP2d; j++) {
0099 sprintf(solname, "%s%i%s_%i", "p", j, "2d", i);
0100 char* Temp = solname;
0101 DrawTrSurf::Set(Temp, tabP2d(j));
0102 // DrawTrSurf::Set(solname, tabP2d(j));
0103 if (i == firstP || i == lastP) {
0104 sprintf(mytext, "%s%i", " ", i);
0105 T2D = new Draw_Text2D(tabP2d(j), mytext, Draw_vert);
0106 dout << T2D;
0107 }
0108 }
0109
0110 // le cas des tangentes aux extremites:
0111 if (i == firstP || i == lastP) {
0112 if (nbP3d != 0 && nbP2d != 0)
0113 Ok = LineTool::Tangency(Line, i, TabV, TabV2d);
0114 else if (nbP2d != 0)
0115 Ok = LineTool::Tangency(Line, i, TabV2d);
0116 else if (nbP3d != 0)
0117 Ok = LineTool::Tangency(Line, i, TabV);
0118
0119 if (Ok) {
0120 for (j = 1; j <= nbP3d; j++) {
0121 sprintf(solname, "%s%i%s_%i", "t", j, "3d", i);
0122 L3d = new Geom_Line(tabP(j), gp_Dir(TabV(j)));
0123 L3dt = new Geom_TrimmedCurve(L3d, 0.0, 0.3);
0124 char* Temp = solname;
0125 DrawTrSurf::Set(Temp, L3dt);
0126 // DrawTrSurf::Set(solname, L3dt);
0127 }
0128 for (j = 1; j <= nbP2d; j++) {
0129 sprintf(solname, "%s%i%s_%i", "t", j, "2d", i);
0130 L2d = new Geom2d_Line(tabP2d(j), gp_Dir2d(TabV2d(j)));
0131 L2dt = new Geom2d_TrimmedCurve(L2d, 0.0, 0.3);
0132 char* Temp = solname;
0133 DrawTrSurf::Set(Temp, L2dt);
0134 // DrawTrSurf::Set(solname, L2dt);
0135 }
0136 }
0137 }
0138 }
0139 dout.Flush();
0140 }
0141
0142
0143 static void DUMP(const AppParCurves_MultiBSpCurve& C)
0144 {
0145 static Standard_Integer nbappel = 0;
0146 Standard_Integer i, j, nbP2d, nbP3d;
0147 Standard_Integer nbpoles = C.NbPoles();
0148 Standard_Integer deg = C.Degree();
0149 const TColStd_Array1OfReal& Knots = C.Knots();
0150 const TColStd_Array1OfInteger& Mults = C.Multiplicities();
0151
0152 Handle(Geom_BSplineCurve) BSp;
0153 Handle(Geom2d_BSplineCurve) BSp2d;
0154
0155 TColgp_Array1OfPnt tabPoles(1, nbpoles);
0156 TColgp_Array1OfPnt2d tabPoles2d(1, nbpoles);
0157 char solname[100];
0158
0159 nbappel++;
0160 for (i = 1; i <= C.NbCurves(); i++) {
0161 if (C.Dimension(i) == 3) {
0162 C.Curve(i, tabPoles);
0163 BSp = new Geom_BSplineCurve(tabPoles, Knots, Mults, deg);
0164 sprintf(solname, "%s%i%s_%i", "c", i, "3d", nbappel);
0165 char* Temp = solname;
0166 DrawTrSurf::Set(Temp, BSp);
0167 // DrawTrSurf::Set(solname, BSp);
0168 }
0169 else {
0170 C.Curve(i, tabPoles2d);
0171 BSp2d = new Geom2d_BSplineCurve(tabPoles2d, Knots, Mults, deg);
0172 sprintf(solname, "%s%i%s_%i", "c", i, "2d", nbappel);
0173 char* Temp = solname;
0174 DrawTrSurf::Set(Temp, BSp2d);
0175 // DrawTrSurf::Set(solname, BSp2d);
0176 }
0177 }
0178 dout.Flush();
0179 }
0180
0181
0182 #endif
0183
0184
0185
0186
0187 //=======================================================================
0188 //function : FirstTangencyVector
0189 //purpose :
0190 //=======================================================================
0191 void Approx_BSplComputeLine::FirstTangencyVector(const MultiLine& Line,
0192 const Standard_Integer index,
0193 math_Vector& V)
0194 const {
0195
0196 Standard_Integer i, j, nbP2d, nbP3d;
0197 nbP3d = LineTool::NbP3d(Line);
0198 nbP2d = LineTool::NbP2d(Line);
0199 Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0200 if (nbP3d == 0) mynbP3d = 1;
0201 if (nbP2d == 0) mynbP2d = 1;
0202 Standard_Boolean Ok = Standard_False;
0203 TColgp_Array1OfVec TabV(1, mynbP3d);
0204 TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
0205
0206 if (nbP3d != 0 && nbP2d != 0)
0207 Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
0208 else if (nbP2d != 0)
0209 Ok = LineTool::Tangency(Line, index, TabV2d);
0210 else if (nbP3d != 0)
0211 Ok = LineTool::Tangency(Line, index, TabV);
0212
0213 if (Ok) {
0214 if (nbP3d != 0) {
0215 j = 1;
0216 for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
0217 V(j) = TabV(i).X();
0218 V(j + 1) = TabV(i).Y();
0219 V(j + 2) = TabV(i).Z();
0220 j += 3;
0221 }
0222 }
0223 if (nbP2d != 0) {
0224 j = nbP3d * 3 + 1;
0225 for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
0226 V(j) = TabV2d(i).X();
0227 V(j + 1) = TabV2d(i).Y();
0228 j += 2;
0229 }
0230 }
0231 }
0232 else {
0233
0234 // recherche d un vecteur tangent par construction d une parabole:
0235 AppParCurves_Constraint firstC, lastC;
0236 firstC = lastC = AppParCurves_PassPoint;
0237 Standard_Integer nbpoles = 3;
0238 math_Vector mypar(index, index + 2);
0239 Parameters(Line, index, index + 2, mypar);
0240 Approx_BSpParLeastSquareOfMyBSplGradient
0241 LSQ(Line, index, index + 2, firstC, lastC, mypar, nbpoles);
0242 AppParCurves_MultiCurve C = LSQ.BezierValue();
0243
0244 gp_Pnt myP;
0245 gp_Vec myV;
0246 gp_Pnt2d myP2d;
0247 gp_Vec2d myV2d;
0248 j = 1;
0249 for (i = 1; i <= nbP3d; i++) {
0250 C.D1(i, 0.0, myP, myV);
0251 V(j) = myV.X();
0252 V(j + 1) = myV.Y();
0253 V(j + 2) = myV.Z();
0254 j += 3;
0255 }
0256 j = nbP3d * 3 + 1;
0257 for (i = nbP3d + 1; i <= nbP3d + nbP2d; i++) {
0258 C.D1(i, 0.0, myP2d, myV2d);
0259 V(j) = myV2d.X();
0260 V(j + 1) = myV2d.Y();
0261 j += 2;
0262 }
0263 }
0264
0265 }
0266
0267
0268 //=======================================================================
0269 //function : LastTangencyVector
0270 //purpose :
0271 //=======================================================================
0272 void Approx_BSplComputeLine::LastTangencyVector(const MultiLine& Line,
0273 const Standard_Integer index,
0274 math_Vector& V)
0275 const {
0276 Standard_Integer i, j, nbP2d, nbP3d;
0277 nbP3d = LineTool::NbP3d(Line);
0278 nbP2d = LineTool::NbP2d(Line);
0279 Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0280 if (nbP3d == 0) mynbP3d = 1;
0281 if (nbP2d == 0) mynbP2d = 1;
0282 Standard_Boolean Ok = Standard_False;
0283 TColgp_Array1OfVec TabV(1, mynbP3d);
0284 TColgp_Array1OfVec2d TabV2d(1, mynbP2d);
0285
0286
0287 if (nbP3d != 0 && nbP2d != 0)
0288 Ok = LineTool::Tangency(Line, index, TabV, TabV2d);
0289 else if (nbP2d != 0)
0290 Ok = LineTool::Tangency(Line, index, TabV2d);
0291 else if (nbP3d != 0)
0292 Ok = LineTool::Tangency(Line, index, TabV);
0293
0294 if (Ok) {
0295 if (nbP3d != 0) {
0296 j = 1;
0297 for (i = TabV.Lower(); i <= TabV.Upper(); i++) {
0298 V(j) = TabV(i).X();
0299 V(j + 1) = TabV(i).Y();
0300 V(j + 2) = TabV(i).Z();
0301 j += 3;
0302 }
0303 }
0304 if (nbP2d != 0) {
0305 j = nbP3d * 3 + 1;
0306 for (i = TabV2d.Lower(); i <= TabV2d.Upper(); i++) {
0307 V(j) = TabV2d(i).X();
0308 V(j + 1) = TabV2d(i).Y();
0309 j += 2;
0310 }
0311 }
0312 }
0313 else {
0314
0315 // recherche d un vecteur tangent par construction d une parabole:
0316 AppParCurves_Constraint firstC, lastC;
0317 firstC = lastC = AppParCurves_PassPoint;
0318 Standard_Integer nbpoles = 3;
0319 math_Vector mypar(index - 2, index);
0320 Parameters(Line, index - 2, index, mypar);
0321 Approx_BSpParLeastSquareOfMyBSplGradient
0322 LSQ(Line, index - 2, index, firstC, lastC, mypar, nbpoles);
0323 AppParCurves_MultiCurve C = LSQ.BezierValue();
0324
0325 gp_Pnt myP;
0326 gp_Vec myV;
0327 gp_Pnt2d myP2d;
0328 gp_Vec2d myV2d;
0329 j = 1;
0330 for (i = 1; i <= nbP3d; i++) {
0331 C.D1(i, 1.0, myP, myV);
0332 V(j) = myV.X();
0333 V(j + 1) = myV.Y();
0334 V(j + 2) = myV.Z();
0335 j += 3;
0336 }
0337 j = nbP3d * 3 + 1;
0338 for (i = nbP3d + 1; i <= nbP3d + nbP2d; i++) {
0339 C.D1(i, 1.0, myP2d, myV2d);
0340 V(j) = myV2d.X();
0341 V(j + 1) = myV2d.Y();
0342 j += 2;
0343 }
0344 }
0345
0346 }
0347
0348
0349
0350 //=======================================================================
0351 //function : SearchFirstLambda
0352 //purpose :
0353 //=======================================================================
0354 Standard_Real Approx_BSplComputeLine::
0355 SearchFirstLambda(const MultiLine& Line,
0356 const math_Vector& aPar,
0357 const TColStd_Array1OfReal& Theknots,
0358 const math_Vector& V,
0359 const Standard_Integer index) const {
0360
0361 // dq/dw = lambda* V = (p2-p1)/(u2-u1)
0362
0363 Standard_Integer nbP2d, nbP3d;
0364 gp_Pnt P1, P2;
0365 gp_Pnt2d P12d, P22d;
0366 nbP3d = LineTool::NbP3d(Line);
0367 nbP2d = LineTool::NbP2d(Line);
0368 Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0369 if (nbP3d == 0) mynbP3d = 1;
0370 if (nbP2d == 0) mynbP2d = 1;
0371 TColgp_Array1OfPnt tabP1(1, mynbP3d), tabP2(1, mynbP3d);
0372 TColgp_Array1OfPnt2d tabP12d(1, mynbP2d), tabP22d(1, mynbP2d);
0373
0374
0375 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP1, tabP12d);
0376 else if (nbP2d != 0) LineTool::Value(Line, index, tabP12d);
0377 else if (nbP3d != 0) LineTool::Value(Line, index, tabP1);
0378
0379 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index + 1, tabP2, tabP22d);
0380 else if (nbP2d != 0) LineTool::Value(Line, index + 1, tabP22d);
0381 else if (nbP3d != 0) LineTool::Value(Line, index + 1, tabP2);
0382
0383
0384 Standard_Real U1 = aPar(index), U2 = aPar(index + 1);
0385 Standard_Real lambda, S;
0386 Standard_Integer low = V.Lower();
0387 Standard_Integer nbknots = Theknots.Length();
0388
0389 if (nbP3d != 0) {
0390 P1 = tabP1(1);
0391 P2 = tabP2(1);
0392 gp_Vec P1P2(P1, P2), myV;
0393 myV.SetCoord(V(low), V(low + 1), V(low + 2));
0394 lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
0395 S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
0396 }
0397 else {
0398 P12d = tabP12d(1);
0399 P22d = tabP22d(1);
0400 gp_Vec2d P1P2(P12d, P22d), myV;
0401 myV.SetCoord(V(low), V(low + 1));
0402 lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
0403 S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
0404 }
0405 return ((S*lambda)*(Theknots(2) - Theknots(1)) / (Theknots(nbknots) - Theknots(1)));
0406
0407 }
0408
0409
0410 //=======================================================================
0411 //function : SearchLastLambda
0412 //purpose :
0413 //=======================================================================
0414 Standard_Real Approx_BSplComputeLine::
0415 SearchLastLambda(const MultiLine& Line,
0416 const math_Vector& aPar,
0417 const TColStd_Array1OfReal& Theknots,
0418 const math_Vector& V,
0419 const Standard_Integer index) const
0420
0421 {
0422 // dq/dw = lambda* V = (p2-p1)/(u2-u1)
0423
0424 Standard_Integer nbP2d, nbP3d;
0425 gp_Pnt P1, P2;
0426 gp_Pnt2d P12d, P22d;
0427 nbP3d = LineTool::NbP3d(Line);
0428 nbP2d = LineTool::NbP2d(Line);
0429 Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0430 if (nbP3d == 0) mynbP3d = 1;
0431 if (nbP2d == 0) mynbP2d = 1;
0432 TColgp_Array1OfPnt tabP(1, mynbP3d), tabP2(1, mynbP3d);
0433 TColgp_Array1OfPnt2d tabP2d(1, mynbP2d), tabP22d(1, mynbP2d);
0434
0435 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index - 1, tabP, tabP2d);
0436 else if (nbP2d != 0) LineTool::Value(Line, index - 1, tabP2d);
0437 else if (nbP3d != 0) LineTool::Value(Line, index - 1, tabP);
0438
0439 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, index, tabP2, tabP22d);
0440 else if (nbP2d != 0) LineTool::Value(Line, index, tabP22d);
0441 else if (nbP3d != 0) LineTool::Value(Line, index, tabP2);
0442
0443
0444 Standard_Real U1 = aPar(index - 1), U2 = aPar(index);
0445 Standard_Real lambda, S;
0446 Standard_Integer low = V.Lower();
0447 Standard_Integer nbknots = Theknots.Length();
0448 if (nbP3d != 0) {
0449 P1 = tabP(1);
0450 P2 = tabP2(1);
0451 gp_Vec P1P2(P1, P2), myV;
0452 myV.SetCoord(V(low), V(low + 1), V(low + 2));
0453 lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
0454 S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
0455 }
0456 else {
0457 P12d = tabP2d(1);
0458 P22d = tabP22d(1);
0459 gp_Vec2d P1P2(P12d, P22d), myV;
0460 myV.SetCoord(V(low), V(low + 1));
0461 lambda = (P1P2.Magnitude()) / (myV.Magnitude()*(U2 - U1));
0462 S = (P1P2.Dot(myV) > 0.0) ? 1.0 : -1.0;
0463 }
0464
0465 return ((S*lambda)*(Theknots(nbknots) - Theknots(nbknots - 1))
0466 / (Theknots(nbknots) - Theknots(1)));
0467 }
0468
0469
0470
0471 //=======================================================================
0472 //function : Approx_BSplComputeLine
0473 //purpose :
0474 //=======================================================================
0475 Approx_BSplComputeLine::Approx_BSplComputeLine
0476 (const MultiLine& Line,
0477 const math_Vector& Parameters,
0478 const Standard_Integer degreemin,
0479 const Standard_Integer degreemax,
0480 const Standard_Real Tolerance3d,
0481 const Standard_Real Tolerance2d,
0482 const Standard_Integer NbIterations,
0483 const Standard_Boolean cutting,
0484 const Standard_Boolean Squares)
0485 {
0486 myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
0487 Parameters.Upper());
0488 for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
0489 myfirstParam->SetValue(i, Parameters(i));
0490 }
0491 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
0492 Par = Approx_IsoParametric;
0493 myPeriodic = Standard_False;
0494 mydegremin = degreemin;
0495 mydegremax = degreemax;
0496 mytol3d = Tolerance3d;
0497 mytol2d = Tolerance2d;
0498 mysquares = Squares;
0499 mycut = cutting;
0500 myitermax = NbIterations;
0501 alldone = Standard_False;
0502 mycont = -1;
0503 myfirstC = AppParCurves_TangencyPoint;
0504 mylastC = AppParCurves_TangencyPoint;
0505 myhasknots = Standard_False;
0506 myhasmults = Standard_False;
0507 currenttol3d = currenttol2d = RealLast();
0508 tolreached = Standard_False;
0509 Perform(Line);
0510 }
0511
0512
0513 //=======================================================================
0514 //function : Approx_BSplComputeLine
0515 //purpose :
0516 //=======================================================================
0517 Approx_BSplComputeLine::Approx_BSplComputeLine
0518 (const math_Vector& Parameters,
0519 const Standard_Integer degreemin,
0520 const Standard_Integer degreemax,
0521 const Standard_Real Tolerance3d,
0522 const Standard_Real Tolerance2d,
0523 const Standard_Integer NbIterations,
0524 const Standard_Boolean cutting,
0525 const Standard_Boolean Squares)
0526 {
0527 myfirstParam = new TColStd_HArray1OfReal(Parameters.Lower(),
0528 Parameters.Upper());
0529 for (Standard_Integer i = Parameters.Lower(); i <= Parameters.Upper(); i++) {
0530 myfirstParam->SetValue(i, Parameters(i));
0531 }
0532 myfirstC = AppParCurves_TangencyPoint;
0533 mylastC = AppParCurves_TangencyPoint;
0534 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
0535 Par = Approx_IsoParametric;
0536 myPeriodic = Standard_False;
0537 mydegremin = degreemin;
0538 mydegremax = degreemax;
0539 mytol3d = Tolerance3d;
0540 mytol2d = Tolerance2d;
0541 mysquares = Squares;
0542 mycut = cutting;
0543 myitermax = NbIterations;
0544 alldone = Standard_False;
0545 myhasknots = Standard_False;
0546 myhasmults = Standard_False;
0547 mycont = -1;
0548 currenttol3d = currenttol2d = RealLast();
0549 tolreached = Standard_False;
0550 }
0551
0552 //=======================================================================
0553 //function : Approx_BSplComputeLine
0554 //purpose :
0555 //=======================================================================
0556 Approx_BSplComputeLine::Approx_BSplComputeLine
0557 (const Standard_Integer degreemin,
0558 const Standard_Integer degreemax,
0559 const Standard_Real Tolerance3d,
0560 const Standard_Real Tolerance2d,
0561 const Standard_Integer NbIterations,
0562 const Standard_Boolean cutting,
0563 const Approx_ParametrizationType parametrization,
0564 const Standard_Boolean Squares)
0565 {
0566 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
0567 Par = parametrization;
0568 myPeriodic = Standard_False;
0569 mydegremin = degreemin;
0570 mydegremax = degreemax;
0571 mytol3d = Tolerance3d;
0572 mytol2d = Tolerance2d;
0573 mysquares = Squares;
0574 mycut = cutting;
0575 myitermax = NbIterations;
0576 myfirstC = AppParCurves_TangencyPoint;
0577 mylastC = AppParCurves_TangencyPoint;
0578 alldone = Standard_False;
0579 myhasknots = Standard_False;
0580 myhasmults = Standard_False;
0581 mycont = -1;
0582 currenttol3d = currenttol2d = RealLast();
0583 tolreached = Standard_False;
0584 }
0585
0586
0587 //=======================================================================
0588 //function : Approx_BSplComputeLine
0589 //purpose :
0590 //=======================================================================
0591 Approx_BSplComputeLine::Approx_BSplComputeLine
0592 (const MultiLine& Line,
0593 const Standard_Integer degreemin,
0594 const Standard_Integer degreemax,
0595 const Standard_Real Tolerance3d,
0596 const Standard_Real Tolerance2d,
0597 const Standard_Integer NbIterations,
0598 const Standard_Boolean cutting,
0599 const Approx_ParametrizationType parametrization,
0600 const Standard_Boolean Squares)
0601 {
0602 myConstraints = new AppParCurves_HArray1OfConstraintCouple(1, 2);
0603 alldone = Standard_False;
0604 mydegremin = degreemin;
0605 mydegremax = degreemax;
0606 mytol3d = Tolerance3d;
0607 mytol2d = Tolerance2d;
0608 mysquares = Squares;
0609 mycut = cutting;
0610 myitermax = NbIterations;
0611 Par = parametrization;
0612 myPeriodic = Standard_False;
0613 myfirstC = AppParCurves_TangencyPoint;
0614 mylastC = AppParCurves_TangencyPoint;
0615 myhasknots = Standard_False;
0616 myhasmults = Standard_False;
0617 mycont = -1;
0618 currenttol3d = currenttol2d = RealLast();
0619 tolreached = Standard_False;
0620 Perform(Line);
0621 }
0622
0623
0624
0625 //=======================================================================
0626 //function : Perform
0627 //purpose :
0628 //=======================================================================
0629 void Approx_BSplComputeLine::Perform(const MultiLine& Line)
0630 {
0631
0632 #if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
0633 if (mydebug) DUMP(Line);
0634 #endif
0635
0636 Standard_Integer i, Thefirstpt, Thelastpt;
0637 Standard_Boolean Finish = Standard_False, begin = Standard_True;
0638
0639 // recherche des vraies contraintes donnees par la Line:
0640 FindRealConstraints(Line);
0641
0642 Thefirstpt = LineTool::FirstPoint(Line);
0643 Thelastpt = LineTool::LastPoint(Line);
0644 Standard_Integer myfirstpt = Thefirstpt;
0645 Standard_Integer mylastpt = Thelastpt;
0646
0647 AppParCurves_ConstraintCouple myCouple1(myfirstpt, realfirstC);
0648 AppParCurves_ConstraintCouple myCouple2(mylastpt, reallastC);
0649 myConstraints->SetValue(1, myCouple1);
0650 myConstraints->SetValue(2, myCouple2);
0651
0652 math_Vector TheParam(Thefirstpt, Thelastpt, 0.0);
0653 if (myfirstParam.IsNull()) {
0654 Parameters(Line, Thefirstpt, Thelastpt, TheParam);
0655 }
0656 else {
0657 for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
0658 TheParam(i + Thefirstpt - 1) = myfirstParam->Value(i);
0659 }
0660 }
0661
0662 myParameters = new TColStd_HArray1OfReal(TheParam.Lower(), TheParam.Upper());
0663 for (i = TheParam.Lower(); i <= TheParam.Upper(); i++) {
0664 myParameters->SetValue(i, TheParam(i));
0665 }
0666 Standard_Integer nbknots = 2;
0667 Standard_Real l;
0668 alldone = Standard_False;
0669
0670 if (!mycut) {
0671
0672 // cas ou on ne desire pas de noeuds supplementaires.
0673 // ==================================================
0674
0675 if (!myhasknots) {
0676 TColStd_Array1OfReal theknots(1, 2);
0677 TColStd_Array1OfInteger themults(1, 2);
0678 theknots(1) = 0.0;
0679 theknots(2) = 1.0;
0680 alldone = Compute(Line, myfirstpt, mylastpt, TheParam, theknots, themults);
0681 }
0682 else {
0683 if (!myhasmults) {
0684 TColStd_Array1OfInteger themults(1, myknots->Length());
0685 alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
0686 myknots->Array1(), themults);
0687 }
0688 else {
0689 alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
0690 myknots->Array1(), mymults->ChangeArray1());
0691 }
0692 }
0693 }
0694 else {
0695
0696 // cas ou on va iterer a partir de noeuds donnes par l''utilisateur
0697 // ou a partir d''une bezier.
0698 // ================================================================
0699
0700 while (!Finish) {
0701
0702 currenttol3d = currenttol2d = RealLast();
0703
0704 if (myhasknots && begin) {
0705
0706 if (!myhasmults) {
0707
0708 // 1er cas: l''utilisateur donne des noeuds de depart mais
0709 // a nous de fixer les multiplicites en fonction de la
0710 // continuite desiree.
0711 // ========================================================
0712
0713 TColStd_Array1OfInteger TheMults(1, myknots->Length());
0714 alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
0715 myknots->Array1(), TheMults);
0716 }
0717 else {
0718
0719 // 2eme cas: l''utilisateur donne des noeuds de depart
0720 // avec leurs multiplicites.
0721 // ===================================================
0722
0723 alldone = Compute(Line, myfirstpt, mylastpt, TheParam,
0724 myknots->Array1(), mymults->ChangeArray1());
0725 }
0726 begin = Standard_False;
0727 }
0728
0729 else {
0730
0731 // 3eme cas: l''utilisateur ne donne aucun noeuds de depart
0732 // ========================================================
0733
0734 TColStd_Array1OfReal Theknots(1, nbknots);
0735 TColStd_Array1OfInteger TheMults(1, nbknots);
0736 Theknots(1) = 0.0;
0737 Theknots(nbknots) = 1.0;
0738 for (i = 2; i <= nbknots - 1; i++) {
0739
0740 l = (mylastpt - myfirstpt)*Standard_Real(i - 1)
0741 / Standard_Real(nbknots - 1);
0742 Standard_Integer ll = (Standard_Integer)(l);
0743 Standard_Real a = l - ll;
0744 Standard_Real p1 = TheParam(ll + myfirstpt);
0745 Standard_Real p2 = TheParam(ll + 1 + myfirstpt);
0746 Theknots(i) = (1. - a)*p1 + a*p2;
0747 }
0748
0749 alldone = Compute(Line, myfirstpt, mylastpt, TheParam, Theknots, TheMults);
0750
0751 }
0752
0753 if (!alldone) nbknots++;
0754 else Finish = Standard_True;
0755 }
0756 }
0757
0758 #if defined(OCCT_DEBUG) && defined( DRAW ) && !defined( WNT )
0759 if (mydebug) DUMP(TheMultiBSpCurve);
0760 #endif
0761
0762 }
0763
0764
0765
0766
0767 //=======================================================================
0768 //function : Parameters
0769 //purpose :
0770 //=======================================================================
0771 const TColStd_Array1OfReal& Approx_BSplComputeLine::Parameters() const
0772 {
0773 return myParameters->Array1();
0774 }
0775
0776
0777
0778 //=======================================================================
0779 //function : Value
0780 //purpose :
0781 //=======================================================================
0782 const AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::Value() const
0783 {
0784 return TheMultiBSpCurve;
0785 }
0786
0787 //=======================================================================
0788 //function : ChangeValue
0789 //purpose :
0790 //=======================================================================
0791 AppParCurves_MultiBSpCurve& Approx_BSplComputeLine::ChangeValue()
0792 {
0793 return TheMultiBSpCurve;
0794 }
0795
0796 //=======================================================================
0797 //function : Parameters
0798 //purpose :
0799 //=======================================================================
0800
0801 void Approx_BSplComputeLine::Parameters(const MultiLine& Line,
0802 const Standard_Integer firstP,
0803 const Standard_Integer lastP,
0804 math_Vector& TheParameters) const
0805 {
0806 Standard_Integer i, j, nbP2d, nbP3d;
0807 Standard_Real dist;
0808 const Standard_Integer aNbp = lastP - firstP + 1;
0809
0810
0811 // The first parameter should always be zero according to all the logic below,
0812 // so division by any value will give zero anyway, so it should never be scaled
0813 // to avoid case when there is only one parameter in the array thus division by zero happens.
0814 TheParameters(firstP) = 0.0;
0815 if (aNbp == 2) {
0816 TheParameters(lastP) = 1.0;
0817 }
0818 else if (Par == Approx_ChordLength || Par == Approx_Centripetal)
0819 {
0820 nbP3d = LineTool::NbP3d(Line);
0821 nbP2d = LineTool::NbP2d(Line);
0822 Standard_Integer mynbP3d = nbP3d, mynbP2d = nbP2d;
0823 if (nbP3d == 0) mynbP3d = 1;
0824 if (nbP2d == 0) mynbP2d = 1;
0825
0826 dist = 0.0;
0827 TColgp_Array1OfPnt tabP(1, mynbP3d);
0828 TColgp_Array1OfPnt tabPP(1, mynbP3d);
0829 TColgp_Array1OfPnt2d tabP2d(1, mynbP2d);
0830 TColgp_Array1OfPnt2d tabPP2d(1, mynbP2d);
0831
0832 for (i = firstP + 1; i <= lastP; i++)
0833 {
0834 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i - 1, tabP, tabP2d);
0835 else if (nbP2d != 0) LineTool::Value(Line, i - 1, tabP2d);
0836 else if (nbP3d != 0) LineTool::Value(Line, i - 1, tabP);
0837
0838 if (nbP3d != 0 && nbP2d != 0) LineTool::Value(Line, i, tabPP, tabPP2d);
0839 else if (nbP2d != 0) LineTool::Value(Line, i, tabPP2d);
0840 else if (nbP3d != 0) LineTool::Value(Line, i, tabPP);
0841 dist = 0.0;
0842 for (j = 1; j <= nbP3d; j++)
0843 {
0844 const gp_Pnt &aP1 = tabP(j),
0845 &aP2 = tabPP(j);
0846 dist += aP2.SquareDistance(aP1);
0847 }
0848 for (j = 1; j <= nbP2d; j++)
0849 {
0850 const gp_Pnt2d &aP12d = tabP2d(j),
0851 &aP22d = tabPP2d(j);
0852
0853 dist += aP22d.SquareDistance(aP12d);
0854 }
0855
0856 dist = Sqrt(dist);
0857 if (Par == Approx_ChordLength)
0858 {
0859 TheParameters(i) = TheParameters(i - 1) + dist;
0860 }
0861 else
0862 {// Par == Approx_Centripetal
0863 TheParameters(i) = TheParameters(i - 1) + Sqrt(dist);
0864 }
0865 }
0866 for (i = firstP + 1; i <= lastP; i++) TheParameters(i) /= TheParameters(lastP);
0867 }
0868 else {
0869 for (i = firstP + 1; i <= lastP; i++) {
0870 TheParameters(i) = (Standard_Real(i) - firstP) /
0871 (Standard_Real(lastP - Standard_Real(firstP)));
0872 }
0873 }
0874 }
0875
0876
0877 //=======================================================================
0878 //function : Compute
0879 //purpose :
0880 //=======================================================================
0881 Standard_Boolean Approx_BSplComputeLine::Compute(const MultiLine& Line,
0882 const Standard_Integer fpt,
0883 const Standard_Integer lpt,
0884 math_Vector& Para,
0885 const TColStd_Array1OfReal& Knots,
0886 TColStd_Array1OfInteger& Mults)
0887 {
0888 Standard_Integer i, deg, nbpoles, multinter;
0889 Standard_Boolean mydone;
0890 Standard_Real Fv, TheTol3d, TheTol2d, l1, l2;
0891 Standard_Integer nbp = lpt - fpt + 1;
0892 mylambda1 = 0.0;
0893 mylambda2 = 0.0;
0894
0895 math_Vector aParams(Para.Lower(), Para.Upper());
0896
0897 for (deg = mydegremin; deg <= mydegremax; deg++) {
0898
0899 aParams = Para;
0900
0901 if (!myhasmults) {
0902 Mults(Mults.Lower()) = deg + 1;
0903 Mults(Mults.Upper()) = deg + 1;
0904 nbpoles = deg + 1;
0905 if (mycont == -1) multinter = 1;
0906 else multinter = Max(1, deg - mycont);
0907 for (i = Mults.Lower() + 1; i <= Mults.Upper() - 1; i++) {
0908 Mults(i) = multinter;
0909 nbpoles += multinter;
0910 }
0911 }
0912 else {
0913 nbpoles = -deg - 1;
0914 for (i = Mults.Lower(); i <= Mults.Upper(); i++) {
0915 nbpoles += Mults.Value(i);
0916 }
0917 }
0918
0919 Standard_Integer nbpolestocompare = nbpoles;
0920 if (realfirstC == AppParCurves_TangencyPoint) nbpolestocompare++;
0921 if (reallastC == AppParCurves_TangencyPoint) nbpolestocompare++;
0922 if (realfirstC == AppParCurves_CurvaturePoint) nbpolestocompare++;
0923 if (reallastC == AppParCurves_CurvaturePoint) nbpolestocompare++;
0924 if (nbpolestocompare > nbp) {
0925 Interpol(Line);
0926 tolreached = Standard_True;
0927 return Standard_True;
0928 }
0929
0930 AppParCurves_MultiBSpCurve mySCU(nbpoles);
0931
0932 if (mysquares) {
0933 Approx_BSpParLeastSquareOfMyBSplGradient SQ(Line, Knots, Mults, fpt, lpt,
0934 realfirstC, reallastC, aParams, nbpoles);
0935 mydone = SQ.IsDone();
0936 if (mydone) {
0937 mySCU = SQ.BSplineValue();
0938 SQ.Error(Fv, TheTol3d, TheTol2d);
0939 }
0940 else continue;
0941 }
0942 else {
0943 if (nbpoles != deg + 1) {
0944
0945 if (deg == mydegremin && (realfirstC >= AppParCurves_TangencyPoint ||
0946 reallastC >= AppParCurves_TangencyPoint)) {
0947 Approx_BSpParLeastSquareOfMyBSplGradient
0948 thefitt(Line, Knots, Mults, fpt, lpt, realfirstC, reallastC, aParams, nbpoles);
0949 mylambda1 = thefitt.FirstLambda()*deg;
0950 mylambda2 = thefitt.LastLambda()*deg;
0951
0952 }
0953 l1 = mylambda1 / deg;
0954 l2 = mylambda2 / deg;
0955
0956 Approx_MyBSplGradient GRAD(Line, fpt, lpt, myConstraints,
0957 aParams, Knots, Mults, deg, mytol3d,
0958 mytol2d, myitermax, l1, l2);
0959
0960 mydone = GRAD.IsDone();
0961 if (mydone) {
0962 mySCU = GRAD.Value();
0963 TheTol3d = GRAD.MaxError3d();
0964 TheTol2d = GRAD.MaxError2d();
0965 }
0966 else continue;
0967 }
0968 else {
0969 Approx_MyGradientbis GRAD2(Line, fpt, lpt, myConstraints,
0970 aParams, deg, mytol3d,
0971 mytol2d, myitermax);
0972 mydone = GRAD2.IsDone();
0973 if (mydone) {
0974 if (GRAD2.Value().NbCurves() == 0)
0975 continue;
0976 mySCU = AppParCurves_MultiBSpCurve(GRAD2.Value(), Knots, Mults);
0977 TheTol3d = GRAD2.MaxError3d();
0978 TheTol2d = GRAD2.MaxError2d();
0979 }
0980 else continue;
0981 }
0982 }
0983 Standard_Boolean save = Standard_True;
0984
0985 for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
0986 if (aParams(i) <= -0.000001 || aParams(i) >= 1.000001) {
0987 save = Standard_False;
0988 break;
0989 }
0990 }
0991
0992 if (mydone) {
0993 if (TheTol3d <= mytol3d && TheTol2d <= mytol2d) {
0994 // Stockage de la multicurve approximee.
0995 tolreached = Standard_True;
0996 TheMultiBSpCurve = mySCU;
0997 currenttol3d = TheTol3d;
0998 currenttol2d = TheTol2d;
0999 if (save) {
1000 for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
1001 myParameters->SetValue(i, aParams(i));
1002 }
1003 }
1004 return Standard_True;
1005 }
1006 }
1007
1008 if (TheTol3d <= currenttol3d && TheTol2d <= currenttol2d) {
1009 TheMultiBSpCurve = mySCU;
1010 currenttol3d = TheTol3d;
1011 currenttol2d = TheTol2d;
1012 if (save) {
1013 for (i = aParams.Lower(); i <= aParams.Upper(); i++) {
1014 myParameters->SetValue(i, aParams(i));
1015 }
1016 }
1017 }
1018
1019 }
1020
1021 return Standard_False;
1022 }
1023
1024
1025
1026 //=======================================================================
1027 //function : SetParameters
1028 //purpose :
1029 //=======================================================================
1030 void Approx_BSplComputeLine::SetParameters(const math_Vector& ThePar)
1031 {
1032 myfirstParam = new TColStd_HArray1OfReal(ThePar.Lower(),
1033 ThePar.Upper());
1034 for (Standard_Integer i = ThePar.Lower(); i <= ThePar.Upper(); i++) {
1035 myfirstParam->SetValue(i, ThePar(i));
1036 }
1037 }
1038
1039
1040 //=======================================================================
1041 //function : SetKnots
1042 //purpose :
1043 //=======================================================================
1044 void Approx_BSplComputeLine::SetKnots(const TColStd_Array1OfReal& Knots)
1045 {
1046 myhasknots = Standard_True;
1047 myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
1048 for (Standard_Integer i = Knots.Lower(); i <= Knots.Upper(); i++) {
1049 myknots->SetValue(i, Knots(i));
1050 }
1051 }
1052
1053
1054 //=======================================================================
1055 //function : SetKnotsAndMultiplicities
1056 //purpose :
1057 //=======================================================================
1058 void Approx_BSplComputeLine::SetKnotsAndMultiplicities
1059 (const TColStd_Array1OfReal& Knots,
1060 const TColStd_Array1OfInteger& Mults)
1061 {
1062 myhasknots = Standard_True;
1063 myhasmults = Standard_True;
1064 Standard_Integer i;
1065 myknots = new TColStd_HArray1OfReal(Knots.Lower(), Knots.Upper());
1066 for (i = Knots.Lower(); i <= Knots.Upper(); i++) {
1067 myknots->SetValue(i, Knots(i));
1068 }
1069 mymults = new TColStd_HArray1OfInteger(Mults.Lower(), Mults.Upper());
1070 for (i = Mults.Lower(); i <= Mults.Upper(); i++) {
1071 mymults->SetValue(i, Mults(i));
1072 }
1073 }
1074
1075 //=======================================================================
1076 //function : Init
1077 //purpose :
1078 //=======================================================================
1079 void Approx_BSplComputeLine::Init(const Standard_Integer degreemin,
1080 const Standard_Integer degreemax,
1081 const Standard_Real Tolerance3d,
1082 const Standard_Real Tolerance2d,
1083 const Standard_Integer NbIterations,
1084 const Standard_Boolean cutting,
1085 const Approx_ParametrizationType parametrization,
1086 const Standard_Boolean Squares)
1087 {
1088 mydegremin = degreemin;
1089 mydegremax = degreemax;
1090 mytol3d = Tolerance3d;
1091 mytol2d = Tolerance2d;
1092 Par = parametrization;
1093 mysquares = Squares;
1094 mycut = cutting;
1095 myitermax = NbIterations;
1096 }
1097
1098
1099
1100 //=======================================================================
1101 //function : SetDegrees
1102 //purpose :
1103 //=======================================================================
1104 void Approx_BSplComputeLine::SetDegrees(const Standard_Integer degreemin,
1105 const Standard_Integer degreemax)
1106 {
1107 mydegremin = degreemin;
1108 mydegremax = degreemax;
1109 }
1110
1111
1112 //=======================================================================
1113 //function : SetTolerances
1114 //purpose :
1115 //=======================================================================
1116 void Approx_BSplComputeLine::SetTolerances(const Standard_Real Tolerance3d,
1117 const Standard_Real Tolerance2d)
1118 {
1119 mytol3d = Tolerance3d;
1120 mytol2d = Tolerance2d;
1121 }
1122
1123
1124 //=======================================================================
1125 //function : SetConstraints
1126 //purpose :
1127 //=======================================================================
1128 void Approx_BSplComputeLine::SetConstraints(const AppParCurves_Constraint FirstC,
1129 const AppParCurves_Constraint LastC)
1130 {
1131 myfirstC = FirstC;
1132 mylastC = LastC;
1133 }
1134
1135 //=======================================================================
1136 //function : SetPeriodic
1137 //purpose :
1138 //=======================================================================
1139 void Approx_BSplComputeLine::SetPeriodic(const Standard_Boolean thePeriodic)
1140 {
1141 myPeriodic = thePeriodic;
1142 }
1143
1144
1145 //=======================================================================
1146 //function : IsAllApproximated
1147 //purpose :
1148 //=======================================================================
1149 Standard_Boolean Approx_BSplComputeLine::IsAllApproximated() const
1150 {
1151 return alldone;
1152 }
1153
1154 //=======================================================================
1155 //function : IsToleranceReached
1156 //purpose :
1157 //=======================================================================
1158 Standard_Boolean Approx_BSplComputeLine::IsToleranceReached() const
1159 {
1160 return tolreached;
1161 }
1162
1163 //=======================================================================
1164 //function : Error
1165 //purpose :
1166 //=======================================================================
1167 void Approx_BSplComputeLine::Error(Standard_Real& tol3d,
1168 Standard_Real& tol2d) const
1169 {
1170 tol3d = currenttol3d;
1171 tol2d = currenttol2d;
1172 }
1173
1174
1175
1176 //=======================================================================
1177 //function : SetContinuity
1178 //purpose :
1179 //=======================================================================
1180 void Approx_BSplComputeLine::SetContinuity(const Standard_Integer C)
1181 {
1182 mycont = C;
1183 }
1184
1185
1186
1187 //=======================================================================
1188 //function : FindRealConstraints
1189 //purpose :
1190 //=======================================================================
1191 void Approx_BSplComputeLine::FindRealConstraints(const MultiLine& Line)
1192 {
1193 realfirstC = myfirstC;
1194 reallastC = mylastC;
1195 Standard_Integer nbP2d, nbP3d;
1196 nbP3d = LineTool::NbP3d(Line);
1197 nbP2d = LineTool::NbP2d(Line);
1198 Standard_Boolean Ok = Standard_False;
1199 TColgp_Array1OfVec TabV(1, Max(1, nbP3d));
1200 TColgp_Array1OfVec2d TabV2d(1, Max(1, nbP2d));
1201 Standard_Integer Thefirstpt = LineTool::FirstPoint(Line);
1202 Standard_Integer Thelastpt = LineTool::LastPoint(Line);
1203
1204 if (myfirstC >= AppParCurves_TangencyPoint) {
1205
1206 if (nbP3d != 0 && nbP2d != 0)
1207 Ok = LineTool::Tangency(Line, Thefirstpt, TabV, TabV2d);
1208 else if (nbP2d != 0)
1209 Ok = LineTool::Tangency(Line, Thefirstpt, TabV2d);
1210 else if (nbP3d != 0)
1211 Ok = LineTool::Tangency(Line, Thefirstpt, TabV);
1212
1213 realfirstC = AppParCurves_PassPoint;
1214 if (Ok) {
1215 realfirstC = AppParCurves_TangencyPoint;
1216 if (myfirstC == AppParCurves_CurvaturePoint) {
1217 if (nbP3d != 0 && nbP2d != 0)
1218 Ok = LineTool::Tangency(Line, Thefirstpt, TabV, TabV2d);
1219 else if (nbP2d != 0)
1220 Ok = LineTool::Tangency(Line, Thefirstpt, TabV2d);
1221 else if (nbP3d != 0)
1222 Ok = LineTool::Tangency(Line, Thefirstpt, TabV);
1223 if (Ok) {
1224 realfirstC = AppParCurves_CurvaturePoint;
1225 }
1226 }
1227 }
1228 }
1229
1230
1231 if (mylastC >= AppParCurves_TangencyPoint) {
1232
1233 if (nbP3d != 0 && nbP2d != 0)
1234 Ok = LineTool::Tangency(Line, Thelastpt, TabV, TabV2d);
1235 else if (nbP2d != 0)
1236 Ok = LineTool::Tangency(Line, Thelastpt, TabV2d);
1237 else if (nbP3d != 0)
1238 Ok = LineTool::Tangency(Line, Thelastpt, TabV);
1239
1240 reallastC = AppParCurves_PassPoint;
1241 if (Ok) {
1242 reallastC = AppParCurves_TangencyPoint;
1243 if (mylastC == AppParCurves_CurvaturePoint) {
1244 if (nbP3d != 0 && nbP2d != 0)
1245 Ok = LineTool::Tangency(Line, Thelastpt, TabV, TabV2d);
1246 else if (nbP2d != 0)
1247 Ok = LineTool::Tangency(Line, Thelastpt, TabV2d);
1248 else if (nbP3d != 0)
1249 Ok = LineTool::Tangency(Line, Thelastpt, TabV);
1250 if (Ok) {
1251 reallastC = AppParCurves_CurvaturePoint;
1252 }
1253 }
1254 }
1255 }
1256
1257 }
1258
1259
1260
1261
1262 //=======================================================================
1263 //function : Interpol
1264 //purpose :
1265 //=======================================================================
1266 void Approx_BSplComputeLine::Interpol(const MultiLine& Line)
1267 {
1268 Standard_Integer i, Thefirstpt, Thelastpt, deg = 3;
1269 mycont = 2;
1270 Thefirstpt = LineTool::FirstPoint(Line);
1271 Thelastpt = LineTool::LastPoint(Line);
1272 math_Vector TheParam(Thefirstpt, Thelastpt, 0.0);
1273 //Par = Approx_ChordLength;
1274 if (myfirstParam.IsNull()) {
1275 Parameters(Line, Thefirstpt, Thelastpt, TheParam);
1276 }
1277 else {
1278 for (i = myfirstParam->Lower(); i <= myfirstParam->Upper(); i++) {
1279 TheParam(i + Thefirstpt - 1) = myfirstParam->Value(i);
1280 }
1281 }
1282 AppParCurves_Constraint Cons = AppParCurves_TangencyPoint;
1283 Standard_Real lambda1, lambda2;
1284 Standard_Real Fv;
1285
1286 // Recherche du nombre de noeuds.
1287 Standard_Integer nbknots, nbpoles, nbpoints;
1288 nbpoints = Thelastpt - Thefirstpt + 1;
1289
1290 if (nbpoints == 2) {
1291 Cons = AppParCurves_NoConstraint;
1292 Standard_Integer mydeg = 1;
1293 Approx_BSpParLeastSquareOfMyBSplGradient
1294 LSQ(Line, Thefirstpt, Thelastpt, Cons, Cons, TheParam, mydeg + 1);
1295 alldone = LSQ.IsDone();
1296 TColStd_Array1OfReal TheKnots(1, 2);
1297 TColStd_Array1OfInteger TheMults(1, 2);
1298 TheKnots(1) = TheParam(Thefirstpt); TheKnots(2) = TheParam(Thelastpt);
1299 TheMults(1) = TheMults(2) = mydeg + 1;
1300 TheMultiBSpCurve =
1301 AppParCurves_MultiBSpCurve(LSQ.BezierValue(), TheKnots, TheMults);
1302 LSQ.Error(Fv, currenttol3d, currenttol2d);
1303
1304 }
1305 else {
1306 nbpoles = nbpoints + 2;
1307 nbknots = nbpoints;
1308
1309 // Resolution:
1310 TColStd_Array1OfReal Theknots(1, nbknots);
1311 Theknots(1) = TheParam(Thefirstpt);
1312 Theknots(nbknots) = TheParam(Thelastpt);
1313 TColStd_Array1OfInteger TheMults(1, nbknots);
1314 TheMults(1) = deg + 1;
1315 TheMults(nbknots) = deg + 1;
1316
1317 Standard_Integer low = TheParam.Lower();
1318 for (i = 2; i <= nbknots - 1; i++) {
1319 Theknots(i) = TheParam(i + low - 1);
1320 TheMults(i) = 1;
1321 }
1322
1323
1324 Standard_Integer nbP = 3 * LineTool::NbP3d(Line) + 2 * LineTool::NbP2d(Line);
1325 math_Vector V1(1, nbP), V2(1, nbP);
1326
1327 if (nbpoints == 3 || nbpoints == 4) {
1328 FirstTangencyVector(Line, Thefirstpt, V1);
1329 lambda1 = SearchFirstLambda(Line, TheParam, Theknots, V1, Thefirstpt);
1330
1331 LastTangencyVector(Line, Thelastpt, V2);
1332 lambda2 = SearchLastLambda(Line, TheParam, Theknots, V2, Thelastpt);
1333
1334 lambda1 = lambda1 / deg;
1335 lambda2 = lambda2 / deg;
1336 }
1337 else {
1338 Standard_Integer nnpol, nnp = Min(nbpoints, 9);
1339 nnpol = nnp;
1340 Standard_Integer lastp = Min(Thelastpt, Thefirstpt + nnp - 1);
1341 Standard_Real U;
1342 Approx_BSpParLeastSquareOfMyBSplGradient
1343 SQ1(Line, Thefirstpt, lastp, Cons, Cons, nnpol);
1344
1345 math_Vector P1(Thefirstpt, lastp);
1346 for (i = Thefirstpt; i <= lastp; i++) P1(i) = TheParam(i);
1347 SQ1.Perform(P1);
1348 const AppParCurves_MultiCurve& C1 = SQ1.BezierValue();
1349 U = 0.0;
1350 TangencyVector(Line, C1, U, V1);
1351
1352 Standard_Integer firstp = Max(Thefirstpt, Thelastpt - nnp + 1);
1353
1354 if (firstp == Thefirstpt && lastp == Thelastpt) {
1355 U = 1.0;
1356 TangencyVector(Line, C1, U, V2);
1357 }
1358 else {
1359 Approx_BSpParLeastSquareOfMyBSplGradient
1360 SQ2(Line, firstp, Thelastpt, Cons, Cons, nnpol);
1361
1362 math_Vector P2(firstp, Thelastpt);
1363 for (i = firstp; i <= Thelastpt; i++) P2(i) = TheParam(i);
1364 SQ2.Perform(P2);
1365 const AppParCurves_MultiCurve& C2 = SQ2.BezierValue();
1366 U = 1.0;
1367 TangencyVector(Line, C2, U, V2);
1368 }
1369
1370
1371 lambda1 = 1. / deg;
1372 lambda1 = lambda1*(Theknots(2) - Theknots(1))
1373 / (Theknots(nbknots) - Theknots(1));
1374 lambda2 = 1. / deg;
1375 lambda2 = lambda2*(Theknots(nbknots) - Theknots(nbknots - 1))
1376 / (Theknots(nbknots) - Theknots(1));
1377
1378 }
1379
1380 if (myPeriodic)
1381 {
1382 V1 = 0.5 * (V1 + V2);
1383 V2 = V1;
1384 }
1385
1386 Approx_BSpParLeastSquareOfMyBSplGradient
1387 SQ(Line, Theknots, TheMults, Thefirstpt, Thelastpt,
1388 Cons, Cons, nbpoles);
1389
1390 SQ.Perform(TheParam, V1, V2, lambda1, lambda2);
1391 alldone = SQ.IsDone();
1392 TheMultiBSpCurve = SQ.BSplineValue();
1393 SQ.Error(Fv, currenttol3d, currenttol2d);
1394 tolreached = Standard_True;
1395 }
1396 myParameters = new TColStd_HArray1OfReal(TheParam.Lower(), TheParam.Upper());
1397 for (i = TheParam.Lower(); i <= TheParam.Upper(); i++) {
1398 myParameters->SetValue(i, TheParam(i));
1399 }
1400 }
1401
1402
1403 //=======================================================================
1404 //function : TangencyVector
1405 //purpose :
1406 //=======================================================================
1407 void Approx_BSplComputeLine::TangencyVector(
1408 const MultiLine& Line,
1409 const AppParCurves_MultiCurve& C,
1410 const Standard_Real U,
1411 math_Vector& V) const
1412 {
1413
1414 Standard_Integer i, j, nbP2d, nbP3d;
1415 nbP3d = LineTool::NbP3d(Line);
1416 nbP2d = LineTool::NbP2d(Line);
1417
1418 gp_Pnt myP;
1419 gp_Vec myV;
1420 gp_Pnt2d myP2d;
1421 gp_Vec2d myV2d;
1422 j = 1;
1423 for (i = 1; i <= nbP3d; i++) {
1424 C.D1(i, U, myP, myV);
1425 V(j) = myV.X();
1426 V(j + 1) = myV.Y();
1427 V(j + 2) = myV.Z();
1428 j += 3;
1429 }
1430 j = nbP3d * 3 + 1;
1431 for (i = nbP3d + 1; i <= nbP3d + nbP2d; i++) {
1432 C.D1(i, U, myP2d, myV2d);
1433 V(j) = myV2d.X();
1434 V(j + 1) = myV2d.Y();
1435 j += 2;
1436 }
1437
1438 }
1439