0024624: Lost word in license statement in source files
[occt.git] / src / ProjLib / ProjLib_ProjectOnSurface.cxx
CommitLineData
b311480e 1// Created on: 1994-09-15
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1994-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 10// by the Free Software Foundation, with special exception defined in the file
11// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12// distribution for complete text of the license and disclaimer of any warranty.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <ProjLib_ProjectOnSurface.ixx>
18
19#include <AppCont_Function.hxx>
20#include <Approx_FitAndDivide.hxx>
21#include <AppParCurves_MultiCurve.hxx>
22#include <Standard_NoSuchObject.hxx>
23#include <Extrema_POnSurf.hxx>
24#include <Precision.hxx>
25#include <BSplCLib.hxx>
26#include <PLib.hxx>
27#include <Adaptor3d_HCurve.hxx>
28#include <Handle_Adaptor3d_HCurve.hxx>
29#include <Geom_BSplineCurve.hxx>
30#include <Handle_Geom_BSplineCurve.hxx>
31#include <TColgp_Array1OfPnt.hxx>
32#include <TColStd_Array1OfReal.hxx>
33#include <TColStd_Array1OfInteger.hxx>
34#include <Extrema_ExtPS.hxx>
35
36
37//=======================================================================
38//function : OnSurface_Value
39//purpose : Evaluate current point of the projected curve
40//=======================================================================
41
42static gp_Pnt OnSurface_Value(const Standard_Real U,
43 const Handle(Adaptor3d_HCurve)& myCurve,
44 Extrema_ExtPS * myExtPS)
45{
46 // on essaie de rendre le point solution le plus proche.
47 myExtPS->Perform(myCurve->Value(U));
48
49 Standard_Real Dist2Min = RealLast();
50 Standard_Integer Index = 0;
51
52 for ( Standard_Integer i = 1; i <= myExtPS->NbExt(); i++) {
53 if ( myExtPS->SquareDistance(i) < Dist2Min) {
54 Index = i;
55 Dist2Min = myExtPS->SquareDistance(Index);
56 }
57 }
58 if ( Index == 0 ) {
59 cout << " Extrema non trouve pour U = " << U << endl;
60 return gp_Pnt(0.,0.,0.);
61 }
62 else {
63 return (myExtPS->Point(Index)).Value();
64 }
65}
66
67//=======================================================================
68//function : OnSurface_D1
69//purpose :
70//=======================================================================
71
72static Standard_Boolean OnSurface_D1(const Standard_Real , // U,
73 gp_Pnt& , // P,
74 gp_Vec& , // V,
75 const Handle(Adaptor3d_HCurve)& , // myCurve,
76 Extrema_ExtPS *) // myExtPS)
77{
78 return Standard_False;
79}
80
81
82//=======================================================================
83// class : ProjLib_OnSurface
84//purpose : Use to approximate the projection on a plane
85//=======================================================================
86
87class ProjLib_OnSurface : public AppCont_Function
88
89{
90 Handle(Adaptor3d_HCurve) myCurve;
91 Extrema_ExtPS *myExtPS;
92
93 public :
94
95 ProjLib_OnSurface(const Handle(Adaptor3d_HCurve) & C,
96 const Handle(Adaptor3d_HSurface) & S)
97 : myCurve(C)
98 {Standard_Real U = myCurve->FirstParameter();
99 gp_Pnt P = myCurve->Value(U);
100 Standard_Real Tol = Precision::PConfusion();
101 myExtPS = new Extrema_ExtPS(P,S->Surface(),Tol,Tol);}
102
103 ~ProjLib_OnSurface() { delete myExtPS; }
104
105 Standard_Real FirstParameter() const
106 {return myCurve->FirstParameter();}
107
108 Standard_Real LastParameter() const
109 {return myCurve->LastParameter();}
110
111 gp_Pnt Value( const Standard_Real t) const
112 {return OnSurface_Value(t,myCurve,myExtPS);}
113
114 Standard_Boolean D1(const Standard_Real t, gp_Pnt& P, gp_Vec& V) const
115 {return OnSurface_D1(t,P,V,myCurve,myExtPS);}
116};
117
118
119
120
121//=====================================================================//
122// //
123// D E S C R I P T I O N O F T H E C L A S S : //
124// //
125// 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 //
126// //
127//=====================================================================//
128
129
130//=======================================================================
131//function : ProjLib_ProjectOnSurface
132//purpose :
133//=======================================================================
134
135ProjLib_ProjectOnSurface::ProjLib_ProjectOnSurface() :
136myIsDone(Standard_False)
137{
138}
139
140//=======================================================================
141//function : ProjLib_ProjectOnSurface
142//purpose :
143//=======================================================================
144
145ProjLib_ProjectOnSurface::ProjLib_ProjectOnSurface
146(const Handle(Adaptor3d_HSurface)& S ) :
147myIsDone(Standard_False)
148{
149 mySurface = S;
150}
151
152void ProjLib_ProjectOnSurface::Load(const Handle(Adaptor3d_HCurve)& C,
153 const Standard_Real Tolerance)
154{
155 myTolerance = Tolerance ;
156 myCurve = C;
157 myIsDone = Standard_False ;
158 if (!mySurface.IsNull()) {
159
160 ProjLib_OnSurface F(myCurve, mySurface);
161
162 Standard_Integer Deg1, Deg2;
163 Deg1 = 8; Deg2 = 8;
164
165 Approx_FitAndDivide Fit(F,Deg1,Deg2,Precision::Approximation(),
166 Precision::PApproximation(),Standard_True);
167 Standard_Integer i;
168 Standard_Integer NbCurves = Fit.NbMultiCurves();
169 Standard_Integer MaxDeg = 0;
170
171 // Pour transformer la MultiCurve en BSpline, il faut que toutes
172 // les Bezier la constituant aient le meme degre -> Calcul de MaxDeg
173 Standard_Integer NbPoles = 1;
174 for (i = 1; i <= NbCurves; i++) {
175 Standard_Integer Deg = Fit.Value(i).Degree();
176 MaxDeg = Max ( MaxDeg, Deg);
177 }
178 NbPoles = MaxDeg * NbCurves + 1; //Poles sur la BSpline
179 TColgp_Array1OfPnt Poles( 1, NbPoles);
180
181 TColgp_Array1OfPnt TempPoles( 1, MaxDeg + 1); //pour augmentation du degre
182
183 TColStd_Array1OfReal Knots( 1, NbCurves + 1); //Noeuds de la BSpline
184
185 Standard_Integer Compt = 1;
186 for (i = 1; i <= Fit.NbMultiCurves(); i++) {
187 Fit.Parameters(i, Knots(i), Knots(i+1));
188
189 AppParCurves_MultiCurve MC = Fit.Value( i); //Charge la Ieme Curve
190 TColgp_Array1OfPnt LocalPoles( 1, MC.Degree() + 1);//Recupere les poles
191 MC.Curve(1, Poles);
192
193 //Augmentation eventuelle du degre
194 Standard_Integer Inc = MaxDeg - MC.Degree();
195 if ( Inc > 0) {
196 BSplCLib::IncreaseDegree( Inc, LocalPoles, PLib::NoWeights(),
197 TempPoles, PLib::NoWeights());
198 //mise a jour des poles de la PCurve
199 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
200 Poles.SetValue( Compt, TempPoles( j));
201 Compt++;
202 }
203 }
204 else {
205 //mise a jour des poles de la PCurve
206 for (Standard_Integer j = 1 ; j <= MaxDeg + 1; j++) {
207 Poles.SetValue( Compt, LocalPoles( j));
208 Compt++;
209 }
210 }
211
212 Compt--;
213 }
214
215 //mise a jour des fields de ProjLib_Approx
216
217 Standard_Integer NbKnots = NbCurves + 1;
218
219 TColStd_Array1OfInteger Mults( 1, NbKnots);
220 Mults.SetValue( 1, MaxDeg + 1);
221 for ( i = 2; i <= NbCurves; i++) {
222 Mults.SetValue( i, MaxDeg);
223 }
224 Mults.SetValue(NbKnots, MaxDeg + 1);
225 myResult =
226 new Geom_BSplineCurve(Poles,
227 Knots,
228 Mults,
229 MaxDeg,
230 Standard_False) ;
231 myIsDone = Standard_True ;
232 }
233}
234
235void ProjLib_ProjectOnSurface::Delete()
236{}
237
238//=======================================================================
239//function : BSpline
240//purpose :
241//=======================================================================
242
243Handle(Geom_BSplineCurve) ProjLib_ProjectOnSurface::BSpline() const
244{
245 Standard_NoSuchObject_Raise_if
246 (!myIsDone,
247 "ProjLib_ProjectOnSurface:BSpline");
248 return myResult ;
249}
250
251//=======================================================================
252//function : IsDone
253//purpose :
254//=======================================================================
255
256Standard_Boolean ProjLib_ProjectOnSurface::IsDone() const
257{
258 return myIsDone;
259}