// Created on: 1997-08-22 // Created by: Sergey SOKOLOV // Copyright (c) 1997-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 #include #include #include #include #include #include #include #include #ifdef OCCT_DEBUG_CHRONO #include static OSD_Chronometer chr_total, chr_init, chr_approx; Standard_Real t_total, t_init, t_approx; void InitChron(OSD_Chronometer& ch) { ch.Reset(); ch.Start(); } void ResultChron( OSD_Chronometer & ch, Standard_Real & time) { Standard_Real tch ; ch.Stop(); ch.Show(tch); time=time +tch; } Standard_IMPORT Standard_Integer uparam_count; Standard_IMPORT Standard_Real t_uparam; #endif //======================================================================= //class : Approx_CurvilinearParameter_EvalCurv //purpose : case of a free 3D curve //======================================================================= class Approx_CurvilinearParameter_EvalCurv : public AdvApprox_EvaluatorFunction { public: Approx_CurvilinearParameter_EvalCurv (const Handle(Approx_CurvlinFunc)& theFunc, Standard_Real First, Standard_Real Last) : fonct(theFunc) { StartEndSav[0] = First; StartEndSav[1] = Last; } virtual void Evaluate (Standard_Integer *Dimension, Standard_Real StartEnd[2], Standard_Real *Parameter, Standard_Integer *DerivativeRequest, Standard_Real *Result, // [Dimension] Standard_Integer *ErrorCode); private: Handle(Approx_CurvlinFunc) fonct; Standard_Real StartEndSav[2]; }; void Approx_CurvilinearParameter_EvalCurv::Evaluate (Standard_Integer * Dimension, Standard_Real * StartEnd, Standard_Real * Param, Standard_Integer * Order, Standard_Real * Result, Standard_Integer * ErrorCode) { *ErrorCode = 0; Standard_Real S = *Param; TColStd_Array1OfReal Res(0, 2); Standard_Integer i; // Dimension is incorrect if (*Dimension != 3) { *ErrorCode = 1; } // Parameter is incorrect if ( S < StartEnd[0] || S > StartEnd[1] ) { *ErrorCode = 2; } if(StartEnd[0] != StartEndSav[0] || StartEnd[1]!= StartEndSav[1]) { fonct->Trim(StartEnd[0],StartEnd[1], Precision::Confusion()); StartEndSav[0]=StartEnd[0]; StartEndSav[1]=StartEnd[1]; } if(!fonct->EvalCase1(S, *Order, Res)) { *ErrorCode = 3; } for(i = 0; i <= 2; i++) Result[i] = Res(i); } Approx_CurvilinearParameter::Approx_CurvilinearParameter(const Handle(Adaptor3d_HCurve)& C3D, const Standard_Real Tol, const GeomAbs_Shape Order, const Standard_Integer MaxDegree, const Standard_Integer MaxSegments) { #ifdef OCCT_DEBUG_CHRONO t_total = t_init = t_approx = t_uparam = 0; uparam_count = 0; InitChron(chr_total); #endif myCase = 1; // Initialisation of input parameters of AdvApprox Standard_Integer Num1DSS=0, Num2DSS=0, Num3DSS=1; Handle(TColStd_HArray1OfReal) OneDTolNul, TwoDTolNul; Handle(TColStd_HArray1OfReal) ThreeDTol = new TColStd_HArray1OfReal(1,Num3DSS); ThreeDTol->Init(Tol); #ifdef OCCT_DEBUG_CHRONO InitChron(chr_init); #endif Handle(Approx_CurvlinFunc) fonct = new Approx_CurvlinFunc(C3D, Tol/10); #ifdef OCCT_DEBUG_CHRONO ResultChron(chr_init, t_init); #endif Standard_Real FirstS = fonct->FirstParameter(); Standard_Real LastS = fonct->LastParameter(); Standard_Integer NbInterv_C2 = fonct->NbIntervals(GeomAbs_C2); TColStd_Array1OfReal CutPnts_C2(1, NbInterv_C2+1); fonct->Intervals(CutPnts_C2,GeomAbs_C2); Standard_Integer NbInterv_C3 = fonct->NbIntervals(GeomAbs_C3); TColStd_Array1OfReal CutPnts_C3(1, NbInterv_C3+1); fonct->Intervals(CutPnts_C3,GeomAbs_C3); AdvApprox_PrefAndRec CutTool(CutPnts_C2,CutPnts_C3); #ifdef OCCT_DEBUG_CHRONO InitChron(chr_approx); #endif Approx_CurvilinearParameter_EvalCurv evC (fonct, FirstS, LastS); AdvApprox_ApproxAFunction aApprox (Num1DSS, Num2DSS, Num3DSS, OneDTolNul, TwoDTolNul, ThreeDTol, FirstS, LastS, Order, MaxDegree, MaxSegments, evC, CutTool); #ifdef OCCT_DEBUG_CHRONO ResultChron(chr_approx, t_approx); #endif myDone = aApprox.IsDone(); myHasResult = aApprox.HasResult(); if (myHasResult) { TColgp_Array1OfPnt Poles(1,aApprox.NbPoles()); aApprox.Poles(1,Poles); Handle(TColStd_HArray1OfReal) Knots = aApprox.Knots(); Handle(TColStd_HArray1OfInteger) Mults = aApprox.Multiplicities(); Standard_Integer Degree = aApprox.Degree(); myCurve3d = new Geom_BSplineCurve(Poles, Knots->Array1(), Mults->Array1(), Degree); } myMaxError3d = aApprox.MaxError(3,1); #ifdef OCCT_DEBUG_CHRONO ResultChron(chr_total, t_total); std::cout<<" total reparametrization time = "<