// Created on: 1996-03-05 // Created by: Joelle CHAUVET // Copyright (c) 1996-1999 Matra Datavision // Copyright (c) 1999-2014 OPEN CASCADE SAS // // This file is part of Open CASCADE Technology software library. // // This library is free software; you can redistribute it and/or modify it under // the terms of the GNU Lesser General Public License version 2.1 as published // by the Free Software Foundation, with special exception defined in the file // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT // distribution for complete text of the license and disclaimer of any warranty. // // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class GeomPlate_MakeApprox_Eval : public AdvApp2Var_EvaluatorFunc2Var { public: GeomPlate_MakeApprox_Eval (const Handle(Geom_Surface)& theSurf) : mySurf (theSurf) {} virtual void Evaluate (Standard_Integer* theDimension, Standard_Real* theUStartEnd, Standard_Real* theVStartEnd, Standard_Integer* theFavorIso, Standard_Real* theConstParam, Standard_Integer* theNbParams, Standard_Real* theParameters, Standard_Integer* theUOrder, Standard_Integer* theVOrder, Standard_Real* theResult, Standard_Integer* theErrorCode) const; private: Handle(Geom_Surface) mySurf; }; void GeomPlate_MakeApprox_Eval::Evaluate (Standard_Integer * Dimension, // Dimension Standard_Real * UStartEnd, // StartEnd[2] in U Standard_Real * VStartEnd, // StartEnd[2] in V Standard_Integer * FavorIso, // Choice of constante, 1 for U, 2 for V Standard_Real * ConstParam, // Value of constant parameter Standard_Integer * NbParams, // Number of parameters N Standard_Real * Parameters, // Values of parameters, Standard_Integer * UOrder, // Derivative Request in U Standard_Integer * VOrder, // Derivative Request in V Standard_Real * Result, // Result[Dimension,N] Standard_Integer * ErrorCode) const // Error Code { *ErrorCode = 0; Standard_Integer idim,jpar; Standard_Real Upar,Vpar; // Dimension incorrecte if (*Dimension!=3) { *ErrorCode = 1; } // Parametres incorrects if (*FavorIso==1) { Upar = *ConstParam; if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) { *ErrorCode = 2; } for (jpar=1;jpar<=*NbParams;jpar++) { Vpar = Parameters[jpar-1]; if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) { *ErrorCode = 2; } } } else { Vpar = *ConstParam; if (( Vpar < VStartEnd[0] ) || ( Vpar > VStartEnd[1] )) { *ErrorCode = 2; } for (jpar=1;jpar<=*NbParams;jpar++) { Upar = Parameters[jpar-1]; if (( Upar < UStartEnd[0] ) || ( Upar > UStartEnd[1] )) { *ErrorCode = 2; } } } // Initialisation for (idim=1;idim<=*Dimension;idim++) { for (jpar=1;jpar<=*NbParams;jpar++) { Result[idim-1+(jpar-1)*(*Dimension)] = 0.; } } Standard_Integer Order = *UOrder + *VOrder; gp_Pnt pnt; // gp_Vec vect, v1, v2, v3, v4, v5, v6, v7, v8, v9; gp_Vec v1, v2, v3, v4, v5; if (*FavorIso==1) { Upar = *ConstParam; switch (Order) { case 0 : for (jpar=1;jpar<=*NbParams;jpar++) { Vpar = Parameters[jpar-1]; pnt = mySurf->Value (Upar, Vpar); Result[(jpar-1)*(*Dimension)] = pnt.X(); Result[1+(jpar-1)*(*Dimension)] = pnt.Y(); Result[2+(jpar-1)*(*Dimension)] = pnt.Z(); } break; case 1 : for (jpar=1;jpar<=*NbParams;jpar++) { Vpar = Parameters[jpar-1]; mySurf->D1 (Upar, Vpar, pnt, v1, v2); if (*UOrder==1) { Result[(jpar-1)*(*Dimension)] = v1.X(); Result[1+(jpar-1)*(*Dimension)] = v1.Y(); Result[2+(jpar-1)*(*Dimension)] = v1.Z(); } else { Result[(jpar-1)*(*Dimension)] = v2.X(); Result[1+(jpar-1)*(*Dimension)] = v2.Y(); Result[2+(jpar-1)*(*Dimension)] = v2.Z(); } } break; case 2 : for (jpar=1;jpar<=*NbParams;jpar++) { Vpar = Parameters[jpar-1]; mySurf->D2 (Upar, Vpar, pnt, v1, v2, v3, v4, v5); if (*UOrder==2) { Result[(jpar-1)*(*Dimension)] = v3.X(); Result[1+(jpar-1)*(*Dimension)] = v3.Y(); Result[2+(jpar-1)*(*Dimension)] = v3.Z(); } else if (*UOrder==1) { Result[(jpar-1)*(*Dimension)] = v5.X(); Result[1+(jpar-1)*(*Dimension)] = v5.Y(); Result[2+(jpar-1)*(*Dimension)] = v5.Z(); } else if (*UOrder==0) { Result[(jpar-1)*(*Dimension)] = v4.X(); Result[1+(jpar-1)*(*Dimension)] = v4.Y(); Result[2+(jpar-1)*(*Dimension)] = v4.Z(); } } break; } } else { Vpar = *ConstParam; switch (Order) { case 0 : for (jpar=1;jpar<=*NbParams;jpar++) { Upar = Parameters[jpar-1]; pnt = mySurf->Value (Upar, Vpar); Result[(jpar-1)*(*Dimension)] = pnt.X(); Result[1+(jpar-1)*(*Dimension)] = pnt.Y(); Result[2+(jpar-1)*(*Dimension)] = pnt.Z(); } break; case 1 : for (jpar=1;jpar<=*NbParams;jpar++) { Upar = Parameters[jpar-1]; mySurf->D1 (Upar, Vpar, pnt, v1, v2); if (*UOrder==1) { Result[(jpar-1)*(*Dimension)] = v1.X(); Result[1+(jpar-1)*(*Dimension)] = v1.Y(); Result[2+(jpar-1)*(*Dimension)] = v1.Z(); } else { Result[(jpar-1)*(*Dimension)] = v2.X(); Result[1+(jpar-1)*(*Dimension)] = v2.Y(); Result[2+(jpar-1)*(*Dimension)] = v2.Z(); } } break; case 2 : for (jpar=1;jpar<=*NbParams;jpar++) { Upar = Parameters[jpar-1]; mySurf->D2 (Upar, Vpar, pnt, v1, v2, v3, v4, v5); if (*UOrder==2) { Result[(jpar-1)*(*Dimension)] = v3.X(); Result[1+(jpar-1)*(*Dimension)] = v3.Y(); Result[2+(jpar-1)*(*Dimension)] = v3.Z(); } else if (*UOrder==1) { Result[(jpar-1)*(*Dimension)] = v5.X(); Result[1+(jpar-1)*(*Dimension)] = v5.Y(); Result[2+(jpar-1)*(*Dimension)] = v5.Z(); } else if (*UOrder==0) { Result[(jpar-1)*(*Dimension)] = v4.X(); Result[1+(jpar-1)*(*Dimension)] = v4.Y(); Result[2+(jpar-1)*(*Dimension)] = v4.Z(); } } break; } } } //======================================================================= //function : GeomPlate_MakeApprox //purpose : //======================================================================= GeomPlate_MakeApprox::GeomPlate_MakeApprox(const Handle(GeomPlate_Surface)& SurfPlate, const AdvApp2Var_Criterion& PlateCrit, const Standard_Real Tol3d, const Standard_Integer Nbmax, const Standard_Integer dgmax, const GeomAbs_Shape Continuity, const Standard_Real EnlargeCoeff) { myPlate = SurfPlate; Standard_Real U0=0., U1=0., V0=0., V1=0.; myPlate->RealBounds(U0, U1, V0, V1); U0 = EnlargeCoeff * U0; U1 = EnlargeCoeff * U1; V0 = EnlargeCoeff * V0; V1 = EnlargeCoeff * V1; Standard_Integer nb1 = 0, nb2 = 0, nb3 = 1; Handle(TColStd_HArray1OfReal) nul1 = new TColStd_HArray1OfReal(1,1); nul1->Init(0.); Handle(TColStd_HArray2OfReal) nul2 = new TColStd_HArray2OfReal(1,1,1,4); nul2->Init(0.); Handle(TColStd_HArray1OfReal) eps3D = new TColStd_HArray1OfReal(1,1); eps3D->Init(Tol3d); Handle(TColStd_HArray2OfReal) epsfr = new TColStd_HArray2OfReal(1,1,1,4); epsfr->Init(Tol3d); GeomAbs_IsoType myType = GeomAbs_IsoV; Standard_Integer myPrec = 0; AdvApprox_DichoCutting myDec; //POP pour WNT GeomPlate_MakeApprox_Eval ev (myPlate); AdvApp2Var_ApproxAFunc2Var AppPlate(nb1, nb2, nb3, nul1,nul1,eps3D, nul2,nul2,epsfr, U0,U1,V0,V1, myType, Continuity, Continuity, myPrec, dgmax,dgmax,Nbmax,ev, // dgmax,dgmax,Nbmax,myPlateSurfEval, PlateCrit,myDec,myDec); mySurface = AppPlate.Surface(1); myAppError = AppPlate.MaxError(3,1); myCritError = AppPlate.CritError(3,1); #ifdef OCCT_DEBUG std::cout<<"Approximation results"<=0) { // contraintes 2d d'ordre 0 myPlate->Constraints(Seq2d); // contraintes 3d correspondantes sur plate Standard_Integer i,nbp=Seq2d.Length(); for(i=1;i<=nbp;i++){ gp_XY P2d=Seq2d.Value(i); gp_Pnt PP; gp_Vec v1h,v2h,v3h; if (CritOrder==0) { // a l'ordre 0 myPlate->D0 (P2d.X(), P2d.Y(), PP); gp_XYZ P3d(PP.X(),PP.Y(),PP.Z()); Seq3d.Append(P3d); } else { // a l'ordre 1 myPlate->D1 (P2d.X(), P2d.Y(), PP, v1h, v2h); v3h=v1h^v2h; gp_XYZ P3d(v3h.X(),v3h.Y(),v3h.Z()); Seq3d.Append(P3d); } } } Standard_Real U0=0., U1=0., V0=0., V1=0.; myPlate->RealBounds(U0, U1, V0, V1); U0 = EnlargeCoeff * U0; U1 = EnlargeCoeff * U1; V0 = EnlargeCoeff * V0; V1 = EnlargeCoeff * V1; Standard_Real seuil = Tol3d; if (CritOrder==0&&Tol3d<10*dmax) { seuil=10*dmax; #ifdef OCCT_DEBUG std::cout<<"Seuil G0 choisi trop faible par rapport au contour. On prend "<Init(0.); Handle(TColStd_HArray2OfReal) nul2 = new TColStd_HArray2OfReal(1,1,1,4); nul2->Init(0.); Handle(TColStd_HArray1OfReal) eps3D = new TColStd_HArray1OfReal(1,1); eps3D->Init(Tol3d); Handle(TColStd_HArray2OfReal) epsfr = new TColStd_HArray2OfReal(1,1,1,4); epsfr->Init(Tol3d); GeomAbs_IsoType myType = GeomAbs_IsoV; Standard_Integer myPrec = 0; AdvApprox_DichoCutting myDec; if (CritOrder==-1) { myPrec = 1; // POP pour NT GeomPlate_MakeApprox_Eval ev (myPlate); AdvApp2Var_ApproxAFunc2Var AppPlate(nb1, nb2, nb3, nul1,nul1,eps3D, nul2,nul2,epsfr, U0,U1,V0,V1, myType, Continuity, Continuity, myPrec, dgmax,dgmax,Nbmax,ev, myDec,myDec); mySurface = AppPlate.Surface(1); myAppError = AppPlate.MaxError(3,1); myCritError = 0.; #ifdef OCCT_DEBUG std::cout<<"Approximation results"<