// Created on: 1994-09-15 // Created by: Bruno DUMORTIER // Copyright (c) 1994-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 //======================================================================= //function : OnSurface_Value //purpose : Evaluate current point of the projected curve //======================================================================= static gp_Pnt OnSurface_Value(const Standard_Real U, const Handle(Adaptor3d_HCurve)& myCurve, Extrema_ExtPS * myExtPS) { // on essaie de rendre le point solution le plus proche. myExtPS->Perform(myCurve->Value(U)); Standard_Real Dist2Min = RealLast(); Standard_Integer Index = 0; for ( Standard_Integer i = 1; i <= myExtPS->NbExt(); i++) { if ( myExtPS->SquareDistance(i) < Dist2Min) { Index = i; Dist2Min = myExtPS->SquareDistance(Index); } } if ( Index == 0 ) { std::cout << " Extrema non trouve pour U = " << U << std::endl; return gp_Pnt(0.,0.,0.); } else { return (myExtPS->Point(Index)).Value(); } } //======================================================================= //function : OnSurface_D1 //purpose : //======================================================================= static Standard_Boolean OnSurface_D1(const Standard_Real , // U, gp_Pnt& , // P, gp_Vec& , // V, const Handle(Adaptor3d_HCurve)& , // myCurve, Extrema_ExtPS *) // myExtPS) { return Standard_False; } //======================================================================= // class : ProjLib_OnSurface //purpose : Use to approximate the projection on a plane //======================================================================= class ProjLib_OnSurface : public AppCont_Function { public: ProjLib_OnSurface(const Handle(Adaptor3d_HCurve) & C, const Handle(Adaptor3d_HSurface) & S) : myCurve(C) { myNbPnt = 1; myNbPnt2d = 0; Standard_Real U = myCurve->FirstParameter(); gp_Pnt P = myCurve->Value(U); Standard_Real Tol = Precision::PConfusion(); myExtPS = new Extrema_ExtPS(P,S->Surface(),Tol,Tol); } ~ProjLib_OnSurface() { delete myExtPS; } Standard_Real FirstParameter() const {return myCurve->FirstParameter();} Standard_Real LastParameter() const {return myCurve->LastParameter();} Standard_Boolean Value(const Standard_Real theT, NCollection_Array1& /*thePnt2d*/, NCollection_Array1& thePnt) const { thePnt(1) = OnSurface_Value(theT, myCurve, myExtPS); return Standard_True; } Standard_Boolean D1(const Standard_Real theT, NCollection_Array1& /*theVec2d*/, NCollection_Array1& theVec) const { gp_Pnt aPnt; return OnSurface_D1(theT, aPnt, theVec(1), myCurve, myExtPS); } private: ProjLib_OnSurface (const ProjLib_OnSurface&); ProjLib_OnSurface& operator= (const ProjLib_OnSurface&); private: Handle(Adaptor3d_HCurve) myCurve; Extrema_ExtPS* myExtPS; }; //=====================================================================// // // // D E S C R I P T I O N O F T H E C L A S S : // // // // P r o j L i b _ A p p r o x P r o j e c t O n P l a n e // // // //=====================================================================// //======================================================================= //function : ProjLib_ProjectOnSurface //purpose : //======================================================================= ProjLib_ProjectOnSurface::ProjLib_ProjectOnSurface() : myTolerance(0.0), myIsDone(Standard_False) { } //======================================================================= //function : ProjLib_ProjectOnSurface //purpose : //======================================================================= ProjLib_ProjectOnSurface::ProjLib_ProjectOnSurface (const Handle(Adaptor3d_HSurface)& S ) : myTolerance(0.0), myIsDone(Standard_False) { mySurface = S; } void ProjLib_ProjectOnSurface::Load(const Handle(Adaptor3d_HCurve)& C, const Standard_Real Tolerance) { myTolerance = Tolerance ; myCurve = C; myIsDone = Standard_False ; if (!mySurface.IsNull()) { ProjLib_OnSurface F(myCurve, mySurface); Standard_Integer Deg1, Deg2; Deg1 = 8; Deg2 = 8; Approx_FitAndDivide Fit(F,Deg1,Deg2,Precision::Approximation(), Precision::PApproximation(),Standard_True); Standard_Integer i; Standard_Integer NbCurves = Fit.NbMultiCurves(); Standard_Integer MaxDeg = 0; // Pour transformer la MultiCurve en BSpline, il faut que toutes // les Bezier la constituant aient le meme degre -> Calcul de MaxDeg Standard_Integer NbPoles = 1; for (i = 1; i <= NbCurves; i++) { Standard_Integer Deg = Fit.Value(i).Degree(); MaxDeg = Max ( MaxDeg, Deg); } NbPoles = MaxDeg * NbCurves + 1; //Poles sur la BSpline TColgp_Array1OfPnt Poles( 1, NbPoles); TColgp_Array1OfPnt TempPoles( 1, MaxDeg + 1); //pour augmentation du degre TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Noeuds de la BSpline Standard_Integer Compt = 1; for (i = 1; i <= Fit.NbMultiCurves(); i++) { Fit.Parameters(i, Knots(i), Knots(i+1)); AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve TColgp_Array1OfPnt LocalPoles( 1, MC.Degree() + 1);//Recupere les poles MC.Curve(1, Poles); //Augmentation eventuelle du degre Standard_Integer Inc = MaxDeg - MC.Degree(); if ( Inc > 0) { BSplCLib::IncreaseDegree( Inc, LocalPoles, BSplCLib::NoWeights(), TempPoles, BSplCLib::NoWeights()); //mise a jour des poles de la PCurve for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) { Poles.SetValue( Compt, TempPoles( j)); Compt++; } } else { //mise a jour des poles de la PCurve for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) { Poles.SetValue( Compt, LocalPoles( j)); Compt++; } } Compt--; } //mise a jour des fields de ProjLib_Approx Standard_Integer NbKnots = NbCurves + 1; TColStd_Array1OfInteger Mults( 1, NbKnots); Mults.SetValue( 1, MaxDeg + 1); for ( i = 2; i <= NbCurves; i++) { Mults.SetValue( i, MaxDeg); } Mults.SetValue(NbKnots, MaxDeg + 1); myResult = new Geom_BSplineCurve(Poles, Knots, Mults, MaxDeg, Standard_False) ; myIsDone = Standard_True ; } } //======================================================================= //function : ~ProjLib_ProjectOnSurface //purpose : //======================================================================= ProjLib_ProjectOnSurface::~ProjLib_ProjectOnSurface() {} //======================================================================= //function : BSpline //purpose : //======================================================================= Handle(Geom_BSplineCurve) ProjLib_ProjectOnSurface::BSpline() const { Standard_NoSuchObject_Raise_if (!myIsDone, "ProjLib_ProjectOnSurface:BSpline"); return myResult ; } //======================================================================= //function : IsDone //purpose : //======================================================================= Standard_Boolean ProjLib_ProjectOnSurface::IsDone() const { return myIsDone; }