Integration of OCCT 6.5.0 from SVN
[occt.git] / src / GeomFill / GeomFill_Profiler.cxx
CommitLineData
7fd59977 1// File: GeomFill_Profiler.cxx
2// Created: Thu Feb 17 11:33:12 1994
3// Author: Bruno DUMORTIER
4// <dub@fuegox>
5
6#include <GeomFill_Profiler.ixx>
7#include <GeomConvert.hxx>
8#include <BSplCLib.hxx>
9#include <Geom_BSplineCurve.hxx>
10#include <Geom_TrimmedCurve.hxx>
11#include <Geom_Conic.hxx>
12#include <GeomConvert_ApproxCurve.hxx>
13
14
15//=======================================================================
16//function : GeomFill_Profiler
17//purpose :
18//=======================================================================
19
20GeomFill_Profiler::GeomFill_Profiler()
21{
22 myIsDone = Standard_False;
23 myIsPeriodic = Standard_True;
24}
25
26
27//=======================================================================
28
29void GeomFill_Profiler::Delete()
30{}
31
32
33//=======================================================================
34//function : AddCurve
35//purpose :
36//=======================================================================
37
38void GeomFill_Profiler::AddCurve(const Handle(Geom_Curve)& Curve)
39{
40 Handle(Geom_Curve) C;
41 //// modified by jgv, 19.01.05 for OCC7354 ////
42 Handle(Geom_Curve) theCurve = Curve;
43 if (theCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
44 theCurve = (*((Handle(Geom_TrimmedCurve)*)&theCurve))->BasisCurve();
45 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
46 {
47 GeomConvert_ApproxCurve appr(Curve, Precision::Confusion(), GeomAbs_C1, 16, 14);
48 if (appr.HasResult())
49 C = appr.Curve();
50 }
51 if (C.IsNull())
52 C = GeomConvert::CurveToBSplineCurve(Curve);
53 /*
54 if ( Curve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
55 C = Handle(Geom_Curve)::DownCast(Curve->Copy());
56 }
57 else {
58 C = GeomConvert::CurveToBSplineCurve(Curve,Convert_QuasiAngular);
59 }
60 */
61 ///////////////////////////////////////////////
62
63 mySequence.Append( C);
64
65 if ( myIsPeriodic && !C->IsPeriodic())
66 myIsPeriodic = Standard_False;
67}
68
69
70//=======================================================================
71//function : Perform
72//purpose :
73//=======================================================================
74
75void GeomFill_Profiler::Perform(const Standard_Real PTol)
76{
77 Standard_Integer i;
78// Standard_Integer myDegree = 0, myNbPoles = 0;
79 Standard_Integer myDegree = 0;
80 Handle(Geom_BSplineCurve) C;
81 Standard_Real U1, U2, UFirst=0, ULast=0;
82 Standard_Real EcartMax = 0.;
83
84 for ( i = 1; i <= mySequence.Length(); i++) {
85 C = Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
86
87 // si non periodique, il faut deperiodiser toutes les courbes
88 // on les segmente ensuite pour assurer K(1) et K(n) de multiplicite
89 // degre + 1
90
91 U2 = C->Knot(C->LastUKnotIndex());
92 U1 = C->Knot(C->FirstUKnotIndex());
93
94 if ( !myIsPeriodic && C->IsPeriodic()) {
95 C->SetNotPeriodic();
96 C->Segment( U1, U2);
97 }
98
99 // evaluate the max degree
100 myDegree = Max( myDegree, C->Degree());
101
102 // Calcul de Max ( Ufin - Udeb) sur l ensemble des courbes.
103 if ( ( U2 - U1) > EcartMax) {
104 EcartMax = U2 - U1;
105 UFirst = U1;
106 ULast = U2;
107 }
108 }
109
110 // increase the degree of the curves to my degree
111 // reparametrize them in the range U1, U2.
112 for ( i = 1; i <= mySequence.Length(); i++) {
113 C = Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
114
115 C->IncreaseDegree( myDegree);
116
117 TColStd_Array1OfReal Knots(1,C->NbKnots());
118 C->Knots(Knots);
119 BSplCLib::Reparametrize(UFirst,ULast,Knots);
120 C->SetKnots(Knots);
121 }
122
123 // inserting in the first curve the knot-vector of all the others.
124 C = Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
125
126 for ( i = 2; i <= mySequence.Length(); i++) {
127 Handle(Geom_BSplineCurve) Ci =
128 Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
129 TColStd_Array1OfReal Ki(1,Ci->NbKnots());
130 Ci->Knots(Ki);
131 TColStd_Array1OfInteger Mi(1,Ci->NbKnots());
132 Ci->Multiplicities(Mi);
133
134 C->InsertKnots( Ki, Mi, PTol, Standard_False);
135 }
136
137 TColStd_Array1OfReal NewKnots(1,C->NbKnots());
138 C->Knots(NewKnots);
139 TColStd_Array1OfInteger NewMults(1,C->NbKnots());
140 C->Multiplicities(NewMults);
141 for ( i = 2; i <= mySequence.Length(); i++) {
142 Handle(Geom_BSplineCurve) Ci =
143 Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
144 Ci->InsertKnots(NewKnots, NewMults, PTol, Standard_False);
145 }
146
147 // essai : tentative mise des poids sur chaque section a une moyenne 1
148 for ( i = 1; i <= mySequence.Length(); i++) {
149 Handle(Geom_BSplineCurve) Ci =
150 Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
151 if ( Ci->IsRational() ) {
152 Standard_Integer np = Ci->NbPoles();
153 Standard_Real sigma = 0.;
154 Standard_Integer j;
155 for ( j = 1; j <= np; j++) {
156 sigma += Ci->Weight(j);
157 }
158 sigma /= np;
159 for ( j= 1; j<= np; j++) {
160 Ci->SetWeight(j,Ci->Weight(j) / sigma);
161 }
162 }
163 }
164 // fin de l essai
165
166 myIsDone = Standard_True;
167}
168
169
170//=======================================================================
171//function : Degree
172//purpose :
173//=======================================================================
174
175Standard_Integer GeomFill_Profiler::Degree() const
176{
177 if ( !myIsDone)
178 StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
179
180 Handle(Geom_BSplineCurve) C =
181 Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
182 return C->Degree();
183}
184
185
186//=======================================================================
187//function : NbPoles
188//purpose :
189//=======================================================================
190
191Standard_Integer GeomFill_Profiler::NbPoles() const
192{
193 if ( !myIsDone)
194 StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
195
196 Handle(Geom_BSplineCurve) C =
197 Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
198 return C->NbPoles();
199}
200
201
202//=======================================================================
203//function : Poles
204//purpose :
205//=======================================================================
206
207void GeomFill_Profiler::Poles(const Standard_Integer Index,
208 TColgp_Array1OfPnt& Poles) const
209{
210 if ( !myIsDone)
211 StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
212
213 Standard_DomainError_Raise_if( Poles.Length() != NbPoles(),
214 "GeomFill_Profiler::Poles");
215 Standard_DomainError_Raise_if( Index < 1 || Index > mySequence.Length(),
216 "GeomFill_Profiler::Poles");
217
218 Handle(Geom_BSplineCurve) C =
219 Handle(Geom_BSplineCurve)::DownCast(mySequence(Index));
220
221 C->Poles(Poles);
222}
223
224
225//=======================================================================
226//function : Weights
227//purpose :
228//=======================================================================
229
230void GeomFill_Profiler::Weights(const Standard_Integer Index,
231 TColStd_Array1OfReal& Weights) const
232{
233 if ( !myIsDone)
234 StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
235
236 Standard_DomainError_Raise_if( Weights.Length() != NbPoles(),
237 "GeomFill_Profiler::Weights");
238 Standard_DomainError_Raise_if( Index < 1 || Index > mySequence.Length(),
239 "GeomFill_Profiler::Weights");
240
241 Handle(Geom_BSplineCurve) C =
242 Handle(Geom_BSplineCurve)::DownCast(mySequence(Index));
243
244 C->Weights(Weights);
245}
246
247
248//=======================================================================
249//function : NbKnots
250//purpose :
251//=======================================================================
252
253Standard_Integer GeomFill_Profiler::NbKnots() const
254{
255 if ( !myIsDone)
256 StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
257
258 Handle(Geom_BSplineCurve) C =
259 Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
260
261 return C->NbKnots();
262}
263
264
265//=======================================================================
266//function : KnotsAndMults
267//purpose :
268//=======================================================================
269
270void GeomFill_Profiler::KnotsAndMults(TColStd_Array1OfReal& Knots,
271 TColStd_Array1OfInteger& Mults ) const
272{
273 if ( !myIsDone)
274 StdFail_NotDone::Raise("GeomFill_Profiler::Degree");
275
276#ifndef No_Exception
277 Standard_Integer n = NbKnots();
278#endif
279 Standard_DomainError_Raise_if( Knots.Length() != n || Mults.Length() != n,
280 "GeomFill_Profiler::KnotsAndMults");
281
282 Handle(Geom_BSplineCurve) C =
283 Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
284
285 C->Knots(Knots);
286 C->Multiplicities(Mults);
287}
288
289