Warning, /include/opencascade/AppBlend_AppSurf.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 <AppDef_MultiLine.hxx>
0016 #include <AppDef_MultiPointConstraint.hxx>
0017 #include <AppParCurves_MultiBSpCurve.hxx>
0018 #include <AppParCurves_MultiCurve.hxx>
0019 #include <AppDef_BSplineCompute.hxx>
0020 #include <AppDef_Compute.hxx>
0021 #include <AppParCurves_Constraint.hxx>
0022 #include <Approx_MCurvesToBSpCurve.hxx>
0023 #include <TColgp_Array1OfPnt.hxx>
0024 #include <TColgp_Array1OfPnt2d.hxx>
0025 #include <TColgp_Array1OfVec.hxx>
0026 #include <TColgp_Array1OfVec2d.hxx>
0027 #include <gp_Vec.hxx>
0028 #include <gp_Vec2d.hxx>
0029 #include <gp_Pnt.hxx>
0030 #include <gp_Pnt2d.hxx>
0031 #include <math_Vector.hxx>
0032 #include <BSplCLib.hxx>
0033
0034 #include <StdFail_NotDone.hxx>
0035 #include <AppParCurves_HArray1OfConstraintCouple.hxx>
0036 #include <AppDef_Variational.hxx>
0037
0038 static Standard_Boolean scal = 1;
0039
0040 Standard_EXPORT Standard_Boolean AppBlend_GetContextSplineApprox();
0041 Standard_EXPORT Standard_Boolean AppBlend_GetContextApproxWithNoTgt();
0042
0043 // modified by EAP (Edward AGAPOV) Fri Jan 4 2002, bug OCC9
0044 // --- keep pipe parametrized like path
0045
0046
0047 //=======================================================================
0048 //function : AppBlend_AppSurf
0049 //purpose :
0050 //=======================================================================
0051
0052 AppBlend_AppSurf::AppBlend_AppSurf ()
0053 : done(Standard_False),
0054 dmin(0),
0055 dmax(0),
0056 tol3d(0.0),
0057 tol2d(0.0),
0058 nbit(0),
0059 udeg(0),
0060 vdeg(0),
0061 knownp(Standard_False),
0062 tol3dreached(0.0),
0063 tol2dreached(0.0),
0064 paramtype(Approx_ChordLength),
0065 continuity(GeomAbs_C2)
0066 {
0067 critweights[0]=0.4;
0068 critweights[1]=0.2;
0069 critweights[2]=0.4;
0070 }
0071
0072
0073 //=======================================================================
0074 //function : AppBlend_AppSurf
0075 //purpose :
0076 //=======================================================================
0077
0078 AppBlend_AppSurf::AppBlend_AppSurf (const Standard_Integer Degmin,
0079 const Standard_Integer Degmax,
0080 const Standard_Real Tol3d,
0081 const Standard_Real Tol2d,
0082 const Standard_Integer NbIt,
0083 const Standard_Boolean KnownParameters)
0084 : done(Standard_False),
0085 dmin(Degmin),
0086 dmax(Degmax),
0087 tol3d(Tol3d),
0088 tol2d(Tol2d),
0089 nbit(NbIt),
0090 udeg(0),
0091 vdeg(0),
0092 knownp(KnownParameters),
0093 tol3dreached(0.0),
0094 tol2dreached(0.0),
0095 paramtype(Approx_ChordLength),
0096 continuity(GeomAbs_C2)
0097 {
0098 critweights[0]=0.4;
0099 critweights[1]=0.2;
0100 critweights[2]=0.4;
0101 }
0102
0103 //=======================================================================
0104 //function : Init
0105 //purpose :
0106 //=======================================================================
0107
0108 void AppBlend_AppSurf::Init (const Standard_Integer Degmin,
0109 const Standard_Integer Degmax,
0110 const Standard_Real Tol3d,
0111 const Standard_Real Tol2d,
0112 const Standard_Integer NbIt,
0113 const Standard_Boolean KnownParameters)
0114 {
0115 done = Standard_False;
0116 dmin = Degmin;
0117 dmax = Degmax;
0118 tol3d = Tol3d;
0119 tol2d = Tol2d;
0120 nbit = NbIt;
0121 knownp = KnownParameters;
0122 continuity = GeomAbs_C2;
0123 paramtype = Approx_ChordLength;
0124 critweights[0]=0.4;
0125 critweights[1]=0.2;
0126 critweights[2]=0.4;
0127 }
0128
0129 //=======================================================================
0130 //function : CriteriumWeight
0131 //purpose : returns the Weights associed to the criterium used in
0132 // the optimization.
0133 //=======================================================================
0134 //
0135 void AppBlend_AppSurf::CriteriumWeight(Standard_Real& W1, Standard_Real& W2, Standard_Real& W3) const
0136 {
0137 W1 = critweights[0];
0138 W2 = critweights[1];
0139 W3 = critweights[2] ;
0140 }
0141 //=======================================================================
0142 //function : SetCriteriumWeight
0143 //purpose :
0144 //=======================================================================
0145
0146 void AppBlend_AppSurf::SetCriteriumWeight(const Standard_Real W1, const Standard_Real W2, const Standard_Real W3)
0147 {
0148 if (W1 < 0 || W2 < 0 || W3 < 0 ) throw Standard_DomainError();
0149 critweights[0] = W1;
0150 critweights[1] = W2;
0151 critweights[2] = W3;
0152 }
0153 //=======================================================================
0154 //function : SetContinuity
0155 //purpose :
0156 //=======================================================================
0157
0158 void AppBlend_AppSurf::SetContinuity (const GeomAbs_Shape TheCont)
0159 {
0160 continuity = TheCont;
0161 }
0162
0163 //=======================================================================
0164 //function : Continuity
0165 //purpose :
0166 //=======================================================================
0167
0168 GeomAbs_Shape AppBlend_AppSurf::Continuity () const
0169 {
0170 return continuity;
0171 }
0172
0173 //=======================================================================
0174 //function : SetParType
0175 //purpose :
0176 //=======================================================================
0177
0178 void AppBlend_AppSurf::SetParType (const Approx_ParametrizationType ParType)
0179 {
0180 paramtype = ParType;
0181 }
0182
0183 //=======================================================================
0184 //function : ParType
0185 //purpose :
0186 //=======================================================================
0187
0188 Approx_ParametrizationType AppBlend_AppSurf::ParType () const
0189 {
0190 return paramtype;
0191 }
0192
0193
0194 //=======================================================================
0195 //function : Perform
0196 //purpose :
0197 //=======================================================================
0198
0199 void AppBlend_AppSurf::Perform(const Handle(TheLine)& Lin,
0200 TheSectionGenerator& F,
0201 const Standard_Boolean SpApprox)
0202
0203 {
0204 InternalPerform(Lin, F, SpApprox, Standard_False);
0205 }
0206
0207 //=======================================================================
0208 //function : PerformSmoothing
0209 //purpose :
0210 //=======================================================================
0211
0212 void AppBlend_AppSurf::PerformSmoothing(const Handle(TheLine)& Lin,
0213 TheSectionGenerator& F)
0214
0215 {
0216 InternalPerform(Lin, F, Standard_True, Standard_True);
0217 }
0218
0219 //=======================================================================
0220 //function : InternalPerform
0221 //purpose :
0222 //=======================================================================
0223
0224 void AppBlend_AppSurf::InternalPerform(const Handle(TheLine)& Lin,
0225 TheSectionGenerator& F,
0226 const Standard_Boolean SpApprox,
0227 const Standard_Boolean UseSmoothing)
0228
0229 {
0230 done = Standard_False;
0231 if (Lin.IsNull()) {return;}
0232 Standard_Integer i,j,k,NbPoint;
0233 Standard_Integer NbUPoles,NbUKnots,NbPoles2d,NbVPoles;
0234 Standard_Boolean withderiv;
0235 AppParCurves_Constraint Cfirst,Clast;
0236
0237 Standard_Real mytol3d,mytol2d;
0238 gp_XYZ newDv;
0239
0240 seqPoles2d.Clear();
0241
0242 NbPoint=Lin->NbPoints();
0243 AppDef_MultiPointConstraint multP;
0244 AppDef_MultiLine multL(NbPoint);
0245
0246 F.GetShape(NbUPoles,NbUKnots,udeg,NbPoles2d);
0247
0248 tabUKnots = new TColStd_HArray1OfReal (1,NbUKnots);
0249 tabUMults = new TColStd_HArray1OfInteger (1,NbUKnots);
0250
0251 F.Knots(tabUKnots->ChangeArray1());
0252 F.Mults(tabUMults->ChangeArray1());
0253
0254 TColgp_Array1OfPnt tabAppP(1,NbUPoles);
0255 TColgp_Array1OfVec tabAppV(1,NbUPoles);
0256
0257 TColgp_Array1OfPnt2d tabP2d(1,Max(1,NbPoles2d));
0258 TColgp_Array1OfVec2d tabV2d(1,Max(1,NbPoles2d));
0259
0260 TColStd_Array1OfReal tabW(1,NbUPoles),tabDW(1,NbUPoles);
0261
0262 TColgp_Array1OfPnt2d tabAppP2d(1,NbPoles2d+NbUPoles); // points2d + poids
0263 TColgp_Array1OfVec2d tabAppV2d(1,NbPoles2d+NbUPoles);
0264
0265
0266 AppParCurves_MultiBSpCurve multC;
0267
0268 // Standard_Boolean SpApprox = Standard_False;
0269
0270 withderiv = F.Section(Lin->Point(1),tabAppP,tabAppV,tabP2d,tabV2d,
0271 tabW,tabDW);
0272
0273 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
0274
0275 for (j=1; j<=NbPoles2d; j++) {
0276 tabAppP2d(j) = tabP2d(j);
0277 if (withderiv) {
0278 tabAppV2d(j) = tabV2d(j);
0279 }
0280 }
0281 for (j=1; j<=NbUPoles; j++) {
0282 // pour les courbes rationnelles il faut multiplier les poles par
0283 // leurs poids respectifs
0284 if (withderiv) {
0285 tabAppV2d(NbPoles2d+j).SetCoord(tabDW(j),0.);
0286 newDv.SetLinearForm(tabDW(j),tabAppP(j).XYZ(),tabW(j),tabAppV(j).XYZ());
0287 tabAppV(j).SetXYZ(newDv);
0288 }
0289 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
0290 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
0291 }
0292
0293 if (withderiv) {
0294 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
0295 Cfirst = AppParCurves_TangencyPoint;
0296 }
0297 else {
0298 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
0299 Cfirst = AppParCurves_PassPoint;
0300 }
0301 multL.SetValue(1,multP);
0302
0303 for (i=2; i<=NbPoint-1; i++) {
0304 if (SpApprox) {
0305 F.Section(Lin->Point(i),tabAppP,tabP2d,tabW);
0306 for (j=1; j<=NbPoles2d; j++) {
0307 tabAppP2d(j) = tabP2d(j);
0308 }
0309 for (j=1; j<=NbUPoles; j++) {
0310 // pour les courbes rationnelles il faut multiplier les poles par
0311 // leurs poids respectifs
0312 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
0313 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
0314 }
0315 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
0316 multL.SetValue(i,multP);
0317 }
0318 // ***********************
0319 else {
0320 withderiv = F.Section(Lin->Point(i),tabAppP,tabAppV,tabP2d,tabV2d,
0321 tabW,tabDW);
0322 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
0323
0324 for (j=1; j<=NbPoles2d; j++) {
0325 tabAppP2d(j) = tabP2d(j);
0326 if (withderiv) {
0327 tabAppV2d(j) = tabV2d(j);
0328 }
0329 }
0330 for (j=1; j<=NbUPoles; j++) {
0331 // pour les courbes rationnelles il faut multiplier les poles par
0332 // leurs poids respectifs
0333 if (withderiv) {
0334 tabAppV2d(NbPoles2d+j).SetCoord(tabDW(j),0.);
0335 newDv.SetLinearForm(tabDW(j),tabAppP(j).XYZ(),tabW(j),tabAppV(j).XYZ());
0336 tabAppV(j).SetXYZ(newDv);
0337 }
0338 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
0339 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
0340 }
0341 if (withderiv) {
0342 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
0343 }
0344 else {
0345 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
0346 }
0347 multL.SetValue(i,multP);
0348 }
0349 // ******************************
0350 }
0351
0352 withderiv = F.Section(Lin->Point(NbPoint),tabAppP,tabAppV,tabP2d,tabV2d,
0353 tabW,tabDW);
0354 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
0355
0356 for (j=1; j<=NbPoles2d; j++) {
0357 tabAppP2d(j) = tabP2d(j);
0358 if (withderiv) {
0359 tabAppV2d(j) = tabV2d(j);
0360 }
0361 }
0362 for (j=1; j<=NbUPoles; j++) {
0363 // pour les courbes rationnelles il faut multiplier les poles par
0364 // leurs poids respectifs
0365 if (withderiv) {
0366 tabAppV2d(NbPoles2d+j).SetCoord(tabDW(j),0.);
0367 newDv.SetLinearForm(tabDW(j),tabAppP(j).XYZ(),tabW(j),tabAppV(j).XYZ());
0368 tabAppV(j).SetXYZ(newDv);
0369 }
0370 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
0371 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
0372 }
0373
0374 if (withderiv) {
0375 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
0376 Clast = AppParCurves_TangencyPoint;
0377 }
0378 else {
0379 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
0380 Clast = AppParCurves_PassPoint;
0381 }
0382 multL.SetValue(NbPoint,multP);
0383
0384 //IFV 04.06.07 occ13904
0385 if(NbPoint == 2) {
0386 dmin = 1;
0387 if(Cfirst == AppParCurves_PassPoint && Clast == AppParCurves_PassPoint) {
0388 dmax = 1;
0389 }
0390 }
0391
0392
0393 if (!SpApprox) {
0394 AppDef_Compute theapprox (dmin,dmax,tol3d,tol2d,nbit, Standard_True, paramtype);
0395 if (knownp) {
0396 math_Vector theParams(1,NbPoint);
0397
0398 // On recale les parametres entre 0 et 1.
0399 theParams(1) = 0.;
0400 theParams(NbPoint) = 1.;
0401 Standard_Real Uf = F.Parameter(Lin->Point(1));
0402 Standard_Real Ul = F.Parameter(Lin->Point(NbPoint))-Uf;
0403 for (i=2; i<NbPoint; i++) {
0404 theParams(i) = (F.Parameter(Lin->Point(i))-Uf)/Ul;
0405 }
0406 AppDef_Compute theAppDef(theParams,dmin,dmax,tol3d,tol2d,nbit,
0407 Standard_True, Standard_True);
0408 theapprox = theAppDef;
0409 }
0410 theapprox.SetConstraints(Cfirst,Clast);
0411 theapprox.Perform(multL);
0412
0413 Standard_Real TheTol3d, TheTol2d;
0414 mytol3d = mytol2d = 0.0;
0415 for (Standard_Integer Index=1; Index<=theapprox.NbMultiCurves(); Index++) {
0416 theapprox.Error(Index, TheTol3d, TheTol2d);
0417 mytol3d = Max(TheTol3d, mytol3d);
0418 mytol2d = Max(TheTol2d, mytol2d);
0419 }
0420 #ifdef OCCT_DEBUG
0421 std::cout << " Tolerances obtenues --> 3d : "<< mytol3d << std::endl;
0422 std::cout << " --> 2d : "<< mytol2d << std::endl;
0423 #endif
0424 multC = theapprox.SplineValue();
0425 }
0426
0427 else {
0428 if(!UseSmoothing) {
0429 Standard_Boolean UseSquares = Standard_False;
0430 if(nbit == 0) UseSquares = Standard_True;
0431 AppDef_BSplineCompute theapprox (dmin,dmax,tol3d,tol2d,nbit,Standard_True, paramtype,
0432 UseSquares);
0433 if(continuity == GeomAbs_C0) {
0434 theapprox.SetContinuity(0);
0435 }
0436 if(continuity == GeomAbs_C1) {
0437 theapprox.SetContinuity(1);
0438 }
0439 else if(continuity == GeomAbs_C2) {
0440 theapprox.SetContinuity(2);
0441 }
0442 else {
0443 theapprox.SetContinuity(3);
0444 }
0445
0446 theapprox.SetConstraints(Cfirst,Clast);
0447
0448 if (knownp) {
0449 math_Vector theParams(1,NbPoint);
0450 // On recale les parametres entre 0 et 1.
0451 theParams(1) = 0.;
0452 theParams(NbPoint) = 1.;
0453 Standard_Real Uf = F.Parameter(Lin->Point(1));
0454 Standard_Real Ul = F.Parameter(Lin->Point(NbPoint))-Uf;
0455 for (i=2; i<NbPoint; i++) {
0456 theParams(i) = (F.Parameter(Lin->Point(i))-Uf)/Ul;
0457 }
0458
0459 theapprox.Init(dmin,dmax,tol3d,tol2d,nbit,Standard_True,
0460 Approx_IsoParametric,Standard_True);
0461 theapprox.SetParameters(theParams);
0462 }
0463 theapprox.Perform(multL);
0464 theapprox.Error(mytol3d,mytol2d);
0465 #ifdef OCCT_DEBUG
0466 std::cout << " Tolerances obtenues --> 3d : "<< mytol3d << std::endl;
0467 std::cout << " --> 2d : "<< mytol2d << std::endl;
0468 #endif
0469 tol3dreached = mytol3d;
0470 tol2dreached = mytol2d;
0471 multC = theapprox.Value();
0472 }
0473 else {
0474 //Variational algo
0475 Handle(AppParCurves_HArray1OfConstraintCouple) TABofCC =
0476 new AppParCurves_HArray1OfConstraintCouple(1, NbPoint);
0477 AppParCurves_Constraint Constraint=AppParCurves_NoConstraint;
0478
0479 for(i = 1; i <= NbPoint; ++i) {
0480 AppParCurves_ConstraintCouple ACC(i,Constraint);
0481 TABofCC->SetValue(i,ACC);
0482 }
0483
0484 TABofCC->ChangeValue(1).SetConstraint(Cfirst);
0485 TABofCC->ChangeValue(NbPoint).SetConstraint(Clast);
0486
0487 AppDef_Variational Variation(multL, 1, NbPoint, TABofCC);
0488
0489 //===================================
0490 Standard_Integer theMaxSegments = 1000;
0491 Standard_Boolean theWithMinMax = Standard_False;
0492 Standard_Boolean theWithCutting = Standard_True;
0493 //===================================
0494
0495 Variation.SetMaxDegree(dmax);
0496 Variation.SetContinuity(continuity);
0497 Variation.SetMaxSegment(theMaxSegments);
0498
0499 Variation.SetTolerance(tol3d);
0500 Variation.SetWithMinMax(theWithMinMax);
0501 Variation.SetWithCutting(theWithCutting);
0502 Variation.SetNbIterations(nbit);
0503
0504 Variation.SetCriteriumWeight(critweights[0], critweights[1], critweights[2]);
0505
0506 if(!Variation.IsCreated()) {
0507 return;
0508 }
0509
0510 if(Variation.IsOverConstrained()) {
0511 return;
0512 }
0513
0514 try {
0515 Variation.Approximate();
0516 }
0517 catch (Standard_Failure const&) {
0518 return;
0519 }
0520
0521 if(!Variation.IsDone()) {
0522 return;
0523 }
0524
0525 mytol3d = Variation.MaxError();
0526 mytol2d = 0.;
0527 #ifdef OCCT_DEBUG
0528 std::cout << " Tolerances obtenues --> 3d : "<< mytol3d << std::endl;
0529 std::cout << " --> 2d : "<< mytol2d << std::endl;
0530 #endif
0531 tol3dreached = mytol3d;
0532 tol2dreached = mytol2d;
0533 multC = Variation.Value();
0534 }
0535 }
0536
0537 vdeg = multC.Degree();
0538 NbVPoles = multC.NbPoles();
0539
0540 tabPoles = new TColgp_HArray2OfPnt (1,NbUPoles,1,NbVPoles);
0541 tabWeights = new TColStd_HArray2OfReal (1,NbUPoles,1,NbVPoles);
0542 tabVKnots = new TColStd_HArray1OfReal (multC.Knots().Lower(),
0543 multC.Knots().Upper());
0544 tabVKnots->ChangeArray1() = multC.Knots();
0545
0546 if (knownp && !UseSmoothing) {
0547 BSplCLib::Reparametrize(F.Parameter(Lin->Point(1)),
0548 F.Parameter(Lin->Point(NbPoint)),
0549 tabVKnots->ChangeArray1());
0550 }
0551
0552 tabVMults = new TColStd_HArray1OfInteger (multC.Multiplicities().Lower(),
0553 multC.Multiplicities().Upper());
0554 tabVMults->ChangeArray1() = multC.Multiplicities();
0555
0556
0557 TColgp_Array1OfPnt newtabP(1,NbVPoles);
0558 Handle(TColgp_HArray1OfPnt2d) newtabP2d =
0559 new TColgp_HArray1OfPnt2d(1,NbVPoles);
0560 for (j=1; j <=NbUPoles; j++) {
0561 multC.Curve(j,newtabP);
0562 multC.Curve(j+NbUPoles+NbPoles2d,newtabP2d->ChangeArray1());
0563 for (k=1; k<=NbVPoles; k++) {
0564 // pour les courbes rationnelles il faut maintenant diviser
0565 // les poles par leurs poids respectifs
0566 tabPoles->ChangeValue(j,k).SetXYZ(newtabP(k).XYZ()/newtabP2d->Value(k).X());
0567 Standard_Real aWeight = newtabP2d->Value(k).X();
0568 if (aWeight < gp::Resolution()) {
0569 done = Standard_False;
0570 return;
0571 }
0572 tabWeights->SetValue(j,k,aWeight);
0573 }
0574 }
0575
0576 for (j=1; j<=NbPoles2d; j++) {
0577 newtabP2d = new TColgp_HArray1OfPnt2d(1,NbVPoles);
0578 multC.Curve(NbUPoles+j,newtabP2d->ChangeArray1());
0579 seqPoles2d.Append(newtabP2d);
0580 }
0581
0582 done = Standard_True;
0583 }
0584
0585
0586 //=======================================================================
0587 //function : Perform
0588 //purpose :
0589 //=======================================================================
0590
0591 void AppBlend_AppSurf::Perform(const Handle(TheLine)& Lin,
0592 TheSectionGenerator& F,
0593 const Standard_Integer NbMaxP)
0594 {
0595 done = Standard_False;
0596 if (Lin.IsNull()) {return;}
0597 Standard_Integer i,j,k;
0598 Standard_Integer NbUPoles,NbUKnots,NbPoles2d,NbVPoles;
0599 Standard_Boolean withderiv;
0600 AppParCurves_Constraint Cfirst=AppParCurves_NoConstraint,Clast=AppParCurves_NoConstraint;
0601
0602 Standard_Real mytol3d = 0.0, mytol2d = 0.0;
0603 gp_XYZ newDv;
0604
0605 seqPoles2d.Clear();
0606
0607 Standard_Integer NbPointTot = Lin->NbPoints();
0608
0609 F.GetShape(NbUPoles,NbUKnots,udeg,NbPoles2d);
0610
0611 tabUKnots = new TColStd_HArray1OfReal (1,NbUKnots);
0612 tabUMults = new TColStd_HArray1OfInteger (1,NbUKnots);
0613
0614 F.Knots(tabUKnots->ChangeArray1());
0615 F.Mults(tabUMults->ChangeArray1());
0616
0617 TColgp_Array1OfPnt tabAppP(1,NbUPoles);
0618 TColgp_Array1OfVec tabAppV(1,NbUPoles);
0619 Standard_Real X,Y,Z,DX,DY,DZ;
0620 X = Y = Z = RealLast();
0621 DX = DY = DZ = RealFirst();
0622
0623 TColgp_Array1OfPnt2d tabP2d(1,Max(1,NbPoles2d));
0624 TColgp_Array1OfVec2d tabV2d(1,Max(1,NbPoles2d));
0625 TColStd_Array1OfReal X2d(1,Max(1,NbPoles2d));X2d.Init(RealLast());
0626 TColStd_Array1OfReal Y2d(1,Max(1,NbPoles2d));Y2d.Init(RealLast());
0627 TColStd_Array1OfReal DX2d(1,Max(1,NbPoles2d));DX2d.Init(RealFirst());
0628 TColStd_Array1OfReal DY2d(1,Max(1,NbPoles2d));DY2d.Init(RealFirst());
0629
0630 TColStd_Array1OfReal tabW(1,NbUPoles),tabDW(1,NbUPoles);
0631
0632 TColgp_Array1OfPnt2d tabAppP2d(1,NbPoles2d+NbUPoles); // points2d + poids
0633 TColgp_Array1OfVec2d tabAppV2d(1,NbPoles2d+NbUPoles);
0634
0635 // On calcule les boites de chaque ligne (box for all lines)
0636 for(i = 1; i <= NbPointTot; i++){
0637 F.Section(Lin->Point(i),tabAppP,tabAppV,tabP2d,tabV2d,tabW,tabDW);
0638 Standard_Real x,y,z;
0639 for (j = 1; j <= NbUPoles; j++)
0640 {
0641 tabAppP(j).Coord(x,y,z);
0642 if(x < X) { X = x; }
0643 if(x > DX) { DX = x; }
0644 if(y < Y) { Y = y; }
0645 if(y > DY) { DY = y; }
0646 if(z < Z) { Z = z; }
0647 if(z > DZ) { DZ = z; }
0648 }
0649 for (j = 1; j <= NbPoles2d; j++)
0650 {
0651 tabP2d(j).Coord(x,y);
0652 if(x < X2d (j)) { X2d (j) = x; }
0653 if(x > DX2d(j)) { DX2d(j) = x; }
0654 if(y < Y2d (j)) { Y2d (j) = y; }
0655 if(y > DY2d(j)) { DY2d(j) = y; }
0656 }
0657 }
0658 // On calcule pour chaque ligne la transformation vers 0 1.
0659 Standard_Real seuil = 1000.*tol3d;
0660 Standard_Real seuil2d = 1000.*tol2d;
0661 if((DX - X) < seuil ){ DX = 1.; X = 0.; }
0662 else{ DX = 1./(DX - X); X *= -DX; }
0663 if((DY - Y) < seuil){ DY = 1.; Y = 0.; }
0664 else{ DY = 1./(DY - Y); Y *= -DY; }
0665 if((DZ - Z) < seuil){ DZ = 1.; Z = 0.; }
0666 else{ DZ = 1./(DZ - Z); Z *= -DZ; }
0667 for(j = 1; j <= NbPoles2d; j++){
0668 if((DX2d(j) - X2d(j)) < seuil2d){ DX2d(j) = 1.; X2d(j) = 0.; }
0669 else{ DX2d(j) = 1./(DX2d(j) - X2d(j)); X2d(j) *= -DX2d(j); }
0670 if((DY2d(j) - Y2d(j)) < seuil2d){ DY2d(j) = 1.; Y2d(j) = 0.; }
0671 else{ DY2d(j) = 1./(DY2d(j) - Y2d(j)); Y2d(j) *= -DY2d(j); }
0672 }
0673 if(!scal){
0674 DX = 1.; X = 0.;
0675 DY = 1.; Y = 0.;
0676 DZ = 1.; Z = 0.;
0677 for(j = 1; j <= NbPoles2d; j++){
0678 DX2d(j) = 1.; X2d(j) = 0.;
0679 DY2d(j) = 1.; Y2d(j) = 0.;
0680 }
0681 }
0682 // modified by eap Thu Jan 3 14:45:22 2002 ___BEGIN___
0683 // Keep "inter-troncons" parameters, not only first and last
0684 // Standard_Real Ufirst=0,Ulast=0;
0685 TColStd_SequenceOfReal aParamSeq;
0686 if (knownp) {
0687 // Ufirst = F.Parameter(Lin->Point(1));
0688 // Ulast = F.Parameter(Lin->Point(NbPointTot));
0689 aParamSeq.Append( F.Parameter (Lin->Point(1)) );
0690 }
0691 // modified by EAP Thu Jan 3 14:45:41 2002 ___END___
0692
0693 Approx_MCurvesToBSpCurve concat;
0694
0695 //On calcule le nombre de troncons.
0696 Standard_Integer nbtronc = NbPointTot/NbMaxP;
0697 Standard_Integer reste = NbPointTot - (nbtronc * NbMaxP);
0698 // On regarde si il faut prendre un troncon de plus.
0699 Standard_Integer nmax = NbMaxP;
0700 if(nbtronc > 0 && reste > 0){
0701 nmax = NbPointTot/(nbtronc + 1);
0702 if(nmax > (2*NbMaxP)/3) {
0703 nbtronc++;
0704 reste = NbPointTot - (nbtronc * nmax);
0705 }
0706 else nmax = NbMaxP;
0707 }
0708 else if(nbtronc == 0){
0709 nbtronc = 1;
0710 nmax = reste;
0711 reste = 0;
0712 }
0713
0714 // Approximate each "troncon" with nb of Bezier's using AppDef_Compute
0715 // and concat them into BSpline with Approx_MCurvesToBSpCurve
0716
0717 TColStd_Array1OfInteger troncsize(1,nbtronc);
0718 TColStd_Array1OfInteger troncstart(1,nbtronc);
0719
0720 Standard_Integer rab = reste/nbtronc + 1;
0721 Standard_Integer start = 1;
0722 Standard_Integer itronc ;
0723 for( itronc = 1; itronc <= nbtronc; itronc++){
0724 troncstart(itronc) = start;
0725 Standard_Integer rabrab = Min(rab,reste);
0726 if(reste > 0){ reste -= rabrab; }
0727 troncsize(itronc) = nmax + rabrab + 1;
0728 start += (nmax + rabrab);
0729 }
0730 troncsize(nbtronc) = troncsize(nbtronc) - 1;
0731 for(itronc = 1; itronc <= nbtronc; itronc++){
0732 Standard_Integer NbPoint = troncsize(itronc);
0733 Standard_Integer StPoint = troncstart(itronc);
0734 AppDef_MultiPointConstraint multP;
0735 AppDef_MultiLine multL(NbPoint);
0736
0737 for (i=1; i<=NbPoint; i++) {
0738 Standard_Integer iLin = StPoint + i - 1;
0739 Standard_Real x,y,z;
0740 withderiv = F.Section(Lin->Point(iLin),tabAppP,tabAppV,tabP2d,tabV2d,
0741 tabW,tabDW);
0742 if(AppBlend_GetContextApproxWithNoTgt()) withderiv = Standard_False;
0743
0744 for (j=1; j<=NbPoles2d; j++) {
0745 tabP2d(j).Coord(x,y);
0746 tabAppP2d(j).SetCoord(DX2d(j)*x+X2d(j),DY2d(j)*y+Y2d(j));
0747 if (withderiv) {
0748 tabV2d(j).Coord(x,y);
0749 tabAppV2d(j).SetCoord(DX2d(j)*x,DY2d(j)*y);
0750 }
0751 }
0752 for (j=1; j<=NbUPoles; j++) {
0753 // pour les courbes rationnelles il faut multiplier les poles par
0754 // leurs poids respectifs
0755 if (withderiv) {
0756 tabAppV2d(NbPoles2d+j).SetCoord(tabDW(j),0.);
0757 newDv.SetLinearForm(tabDW(j),tabAppP(j).XYZ(),tabW(j),tabAppV(j).XYZ());
0758 tabAppV(j).SetCoord(DX*newDv.X(),DY*newDv.Y(),DZ*newDv.Z());
0759 }
0760 tabAppP(j).SetXYZ(tabAppP(j).XYZ() * tabW(j));
0761 tabAppP2d(NbPoles2d+j).SetCoord(tabW(j),0.);
0762 tabAppP(j).Coord(x,y,z);
0763 tabAppP(j).SetCoord(DX*x+X,DY*y+Y,DZ*z+Z);
0764 }
0765 if (withderiv) {
0766 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d,tabAppV,tabAppV2d);
0767 if(i == 1) Cfirst = AppParCurves_TangencyPoint;
0768 else if(i == NbPoint) Clast = AppParCurves_TangencyPoint;
0769 }
0770 else {
0771 multP = AppDef_MultiPointConstraint(tabAppP,tabAppP2d);
0772 if(i == 1) Cfirst = AppParCurves_PassPoint;
0773 else if(i == NbPoint) Clast = AppParCurves_PassPoint;
0774 }
0775 multL.SetValue(i,multP);
0776 }
0777
0778
0779 //IFV 04.06.07 occ13904
0780 if(NbPoint == 2) {
0781 dmin = 1;
0782 if(Cfirst == AppParCurves_PassPoint && Clast == AppParCurves_PassPoint) {
0783 dmax = 1;
0784 }
0785 }
0786
0787 // modified by EAP Thu Jan 3 15:44:13 2002 ___BEGIN___
0788 Standard_Real Ufloc=0., Ulloc=0.;
0789 AppDef_Compute theapprox (dmin,dmax,tol3d,tol2d,nbit);
0790 if (knownp) {
0791 math_Vector theParams(1,NbPoint);
0792 // On recale les parametres entre 0 et 1.
0793 /*Standard_Real*/ Ufloc = F.Parameter(Lin->Point(StPoint));
0794 /*Standard_Real*/ Ulloc = F.Parameter(Lin->Point(StPoint+NbPoint-1));
0795 // modified by EAP Thu Jan 3 15:45:17 2002 ___END___
0796 for (i=1; i <= NbPoint; i++) {
0797 Standard_Integer iLin = StPoint + i - 1;
0798 theParams(i) = (F.Parameter(Lin->Point(iLin))-Ufloc)/(Ulloc - Ufloc);
0799 }
0800 AppDef_Compute theAppDef1(theParams,dmin,dmax,tol3d,tol2d,nbit, Standard_True,Standard_True);
0801 theapprox = theAppDef1;
0802 }
0803 theapprox.SetConstraints(Cfirst,Clast);
0804 theapprox.Perform(multL);
0805
0806 // modified by EAP Thu Jan 3 16:00:43 2002 ___BEGIN___
0807 // To know internal parameters if multicurve is approximated by several Bezier's
0808 TColStd_SequenceOfReal aPoleDistSeq;
0809 Standard_Real aWholeDist=0;
0810 // modified by EAP Thu Jan 3 16:45:48 2002 ___END___
0811 Standard_Real TheTol3d, TheTol2d;
0812 for (Standard_Integer Index=1; Index<=theapprox.NbMultiCurves(); Index++) {
0813 AppParCurves_MultiCurve& mucu = theapprox.ChangeValue(Index);
0814 theapprox.Error(Index, TheTol3d, TheTol2d);
0815 mytol3d = Max(TheTol3d/DX, mytol3d);
0816 mytol3d = Max(TheTol3d/DY, mytol3d);
0817 mytol3d = Max(TheTol3d/DZ, mytol3d);
0818 for(j = 1; j <= NbUPoles; j++){
0819 mucu.Transform(j,
0820 -X/DX,1./DX,
0821 -Y/DY,1./DY,
0822 -Z/DZ,1./DZ);
0823 }
0824 for(j = 1; j <= NbPoles2d; j++){
0825 mucu.Transform2d(j + NbUPoles,
0826 -X2d(j)/DX2d(j),1./DX2d(j),
0827 -Y2d(j)/DY2d(j),1./DY2d(j));
0828 mytol2d = Max(TheTol2d/DX2d(j), mytol2d);
0829 mytol2d = Max(TheTol2d/DY2d(j), mytol2d);
0830 }
0831 concat.Append(mucu);
0832
0833 // modified by EAP Thu Jan 3 15:45:23 2002 ___BEGIN___
0834 if (knownp && theapprox.NbMultiCurves() > 1)
0835 {
0836 gp_Pnt aFirstPole = mucu.Pole(Index, 1);
0837 gp_Pnt aLastPole = mucu.Pole(Index, mucu.NbPoles());
0838 aPoleDistSeq.Append (aFirstPole.Distance(aLastPole));
0839 aWholeDist += aPoleDistSeq.Last();
0840 }
0841 }
0842 if (knownp)
0843 {
0844 Standard_Integer iDist;
0845 Standard_Real iU = Ufloc;
0846 for (iDist=1; iDist<aPoleDistSeq.Length(); iDist++)
0847 {
0848 iU += aPoleDistSeq(iDist) / aWholeDist * (Ulloc - Ufloc);
0849 //cout << "Internal: " << iU << endl;
0850 aParamSeq.Append(iU);
0851 }
0852 aParamSeq.Append(Ulloc);
0853 }
0854 // modified by EAP Thu Jan 3 15:45:27 2002 ___END___
0855 }
0856 #ifdef OCCT_DEBUG
0857 std::cout << " Tolerances obtenues --> 3d : "<< mytol3d << std::endl;
0858 std::cout << " --> 2d : "<< mytol2d << std::endl;
0859 #endif
0860 tol3dreached = mytol3d;
0861 tol2dreached = mytol2d;
0862 concat.Perform();
0863 const AppParCurves_MultiBSpCurve& multC = concat.Value();
0864 vdeg = multC.Degree();
0865 NbVPoles = multC.NbPoles();
0866
0867 tabPoles = new TColgp_HArray2OfPnt (1,NbUPoles,1,NbVPoles);
0868 tabWeights = new TColStd_HArray2OfReal (1,NbUPoles,1,NbVPoles);
0869 tabVKnots = new TColStd_HArray1OfReal (multC.Knots().Lower(),
0870 multC.Knots().Upper());
0871 tabVKnots->ChangeArray1() = multC.Knots();
0872
0873 if (knownp) {
0874 // modified by EAP Fri Jan 4 12:07:30 2002 ___BEGIN___
0875 if (aParamSeq.Length() != tabVKnots->Length())
0876 {
0877 BSplCLib::Reparametrize(F.Parameter(Lin->Point(1)),
0878 F.Parameter(Lin->Point(Lin->NbPoints())),
0879 tabVKnots->ChangeArray1()
0880 );
0881 #ifdef OCCT_DEBUG
0882 std::cout << "Warning: AppBlend_AppSurf::Perform(), bad length of aParamSeq: " <<
0883 aParamSeq.Length() << " instead of " << tabVKnots->Length() << std::endl;
0884 #endif
0885 }
0886 else
0887 {
0888 Standard_Integer iKnot, iTabKnot = tabVKnots->Lower();
0889 for (iKnot=1; iKnot<=aParamSeq.Length(); iKnot++, iTabKnot++)
0890 {
0891 //cout << "Replace " << tabVKnots->Value(iTabKnot) << " with " << aParamSeq(iKnot) << endl;
0892 tabVKnots->SetValue(iTabKnot, aParamSeq(iKnot));
0893 }
0894 }
0895 // modified by EAP Fri Jan 4 12:07:35 2002 ___END___
0896 }
0897
0898 tabVMults = new TColStd_HArray1OfInteger (multC.Multiplicities().Lower(),
0899 multC.Multiplicities().Upper());
0900 tabVMults->ChangeArray1() = multC.Multiplicities();
0901
0902
0903 TColgp_Array1OfPnt newtabP(1,NbVPoles);
0904 Handle(TColgp_HArray1OfPnt2d) newtabP2d =
0905 new TColgp_HArray1OfPnt2d(1,NbVPoles);
0906 for (j=1; j <=NbUPoles; j++) {
0907 multC.Curve(j,newtabP);
0908 multC.Curve(j+NbUPoles+NbPoles2d,newtabP2d->ChangeArray1());
0909 for (k=1; k<=NbVPoles; k++) {
0910 // pour les courbes rationnelles il faut maintenant diviser
0911 // les poles par leurs poids respectifs
0912 tabPoles->ChangeValue(j,k).SetXYZ(newtabP(k).XYZ()/newtabP2d->Value(k).X());
0913 Standard_Real aWeight = newtabP2d->Value(k).X();
0914 if (aWeight < gp::Resolution()) {
0915 done = Standard_False;
0916 return;
0917 }
0918 tabWeights->SetValue(j,k,aWeight);
0919 }
0920 }
0921
0922 for (j=1; j<=NbPoles2d; j++) {
0923 newtabP2d = new TColgp_HArray1OfPnt2d(1,NbVPoles);
0924 multC.Curve(NbUPoles+j,newtabP2d->ChangeArray1());
0925 seqPoles2d.Append(newtabP2d);
0926 }
0927
0928 done = Standard_True;
0929 }
0930
0931
0932 //=======================================================================
0933 //function : SurfShape
0934 //purpose :
0935 //=======================================================================
0936
0937 void AppBlend_AppSurf::SurfShape (Standard_Integer& UDegree,
0938 Standard_Integer& VDegree,
0939 Standard_Integer& NbUPoles,
0940 Standard_Integer& NbVPoles,
0941 Standard_Integer& NbUKnots,
0942 Standard_Integer& NbVKnots) const
0943 {
0944 if (!done) {throw StdFail_NotDone();}
0945 UDegree = udeg;
0946 VDegree = vdeg;
0947 NbUPoles = tabPoles->ColLength();
0948 NbVPoles = tabPoles->RowLength();
0949 NbUKnots = tabUKnots->Length();
0950 NbVKnots = tabVKnots->Length();
0951 }
0952
0953
0954 void AppBlend_AppSurf::Surface(TColgp_Array2OfPnt& TPoles,
0955 TColStd_Array2OfReal& TWeights,
0956 TColStd_Array1OfReal& TUKnots,
0957 TColStd_Array1OfReal& TVKnots,
0958 TColStd_Array1OfInteger& TUMults,
0959 TColStd_Array1OfInteger& TVMults) const
0960
0961 {
0962 if (!done) {throw StdFail_NotDone();}
0963 TPoles = tabPoles->Array2();
0964 TWeights = tabWeights->Array2();
0965 TUKnots = tabUKnots->Array1();
0966 TUMults = tabUMults->Array1();
0967 TVKnots = tabVKnots->Array1();
0968 TVMults = tabVMults->Array1();
0969 }
0970
0971 //=======================================================================
0972 //function : Curves2dShape
0973 //purpose :
0974 //=======================================================================
0975
0976 void AppBlend_AppSurf::Curves2dShape(Standard_Integer& Degree,
0977 Standard_Integer& NbPoles,
0978 Standard_Integer& NbKnots) const
0979 {
0980 if (!done) {throw StdFail_NotDone();}
0981 if (seqPoles2d.Length() == 0) {throw Standard_DomainError();}
0982 Degree = vdeg;
0983 NbPoles = tabPoles->ColLength();
0984 NbKnots = tabVKnots->Length();
0985 }
0986
0987 //=======================================================================
0988 //function : Curve2d
0989 //purpose :
0990 //=======================================================================
0991
0992 void AppBlend_AppSurf::Curve2d(const Standard_Integer Index,
0993 TColgp_Array1OfPnt2d& TPoles,
0994 TColStd_Array1OfReal& TKnots,
0995 TColStd_Array1OfInteger& TMults) const
0996 {
0997 if (!done) {throw StdFail_NotDone();}
0998 if (seqPoles2d.Length() == 0) {throw Standard_DomainError();}
0999 TPoles = seqPoles2d(Index)->Array1();
1000 TKnots = tabVKnots->Array1();
1001 TMults = tabVMults->Array1();
1002 }
1003
1004 //=======================================================================
1005 //function : TolCurveOnSurf
1006 //purpose :
1007 //=======================================================================
1008
1009 Standard_Real AppBlend_AppSurf::TolCurveOnSurf(const Standard_Integer) const
1010 {
1011 return tol3dreached; //On ne s'embete pas !!
1012 }
1013
1014
1015