Back to home page

EIC code displayed by LXR

 
 

    


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