0031304: Configuration - TKACIS building failure due to duplicated symbol GeomFillFus...
[occt.git] / src / GeomFill / GeomFill_Profiler.cxx
CommitLineData
b311480e 1// Created on: 1994-02-17
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
42cf5bc1 17
7fd59977 18#include <BSplCLib.hxx>
19#include <Geom_BSplineCurve.hxx>
7fd59977 20#include <Geom_Conic.hxx>
ec357c5c 21#include <Geom_Curve.hxx>
42cf5bc1 22#include <Geom_TrimmedCurve.hxx>
23#include <GeomConvert.hxx>
24#include <GeomConvert_ApproxCurve.hxx>
25#include <GeomFill_Profiler.hxx>
26#include <Standard_DomainError.hxx>
27#include <StdFail_NotDone.hxx>
7fd59977 28
93442c6f 29//=======================================================================
30//function : UnifyByInsertingAllKnots
31//purpose :
32//=======================================================================
e83d440f 33static void UnifyByInsertingAllKnots(TColGeom_SequenceOfCurve& theCurves,
93442c6f 34 const Standard_Real PTol)
35{
36 // inserting in the first curve the knot-vector of all the others.
37 Handle(Geom_BSplineCurve) C = Handle(Geom_BSplineCurve)::DownCast(theCurves(1));
38
39 Standard_Integer i;
40 for ( i = 2; i <= theCurves.Length(); i++) {
41 Handle(Geom_BSplineCurve) Ci =
42 Handle(Geom_BSplineCurve)::DownCast(theCurves(i));
43 TColStd_Array1OfReal Ki(1,Ci->NbKnots());
44 Ci->Knots(Ki);
45 TColStd_Array1OfInteger Mi(1,Ci->NbKnots());
46 Ci->Multiplicities(Mi);
47
48 C->InsertKnots( Ki, Mi, PTol, Standard_False);
49 }
50
51 TColStd_Array1OfReal NewKnots(1,C->NbKnots());
52 C->Knots(NewKnots);
53 TColStd_Array1OfInteger NewMults(1,C->NbKnots());
54 C->Multiplicities(NewMults);
55 for ( i = 2; i <= theCurves.Length(); i++) {
56 Handle(Geom_BSplineCurve) Ci =
57 Handle(Geom_BSplineCurve)::DownCast(theCurves(i));
58 Ci->InsertKnots(NewKnots, NewMults, PTol, Standard_False);
59 }
60
61 // essai : tentative mise des poids sur chaque section a une moyenne 1
62 for ( i = 1; i <= theCurves.Length(); i++) {
63 Handle(Geom_BSplineCurve) Ci =
64 Handle(Geom_BSplineCurve)::DownCast(theCurves(i));
65 if ( Ci->IsRational() ) {
66 Standard_Integer np = Ci->NbPoles();
67 Standard_Real sigma = 0.;
68 Standard_Integer j;
69 for ( j = 1; j <= np; j++) {
70 sigma += Ci->Weight(j);
71 }
72 sigma /= np;
73 for ( j= 1; j<= np; j++) {
74 Ci->SetWeight(j,Ci->Weight(j) / sigma);
75 }
76 }
77 }
78 // fin de l essai
79}
80
81//=======================================================================
82//function : UnifyBySettingMiddleKnots
83//purpose :
84//=======================================================================
e83d440f 85static void UnifyBySettingMiddleKnots(TColGeom_SequenceOfCurve& theCurves)
93442c6f 86{
87 Standard_Integer i, j;
88
89 Handle(Geom_BSplineCurve) C = Handle(Geom_BSplineCurve)::DownCast(theCurves(1));
90
91 Standard_Integer NbKnots = C->NbKnots();
92 Standard_Real ULast = C->Knot(C->LastUKnotIndex());
93 Standard_Real UFirst = C->Knot(C->FirstUKnotIndex());
94
95 //Set middle values of knots
96 TColStd_Array1OfReal NewKnots(1, NbKnots);
97 NewKnots(1) = UFirst;
98 NewKnots(NbKnots) = ULast;
99 for (j = 2; j < NbKnots; j++)
100 {
101 Standard_Real aMidKnot = 0.;
102 for (i = 1; i <= theCurves.Length(); i++)
103 {
51740958 104 Handle(Geom_BSplineCurve) Ctemp = Handle(Geom_BSplineCurve)::DownCast(theCurves(i));
105 aMidKnot += Ctemp->Knot(j);
93442c6f 106 }
107 aMidKnot /= theCurves.Length();
108 NewKnots(j) = aMidKnot;
109 }
110
111 for (i = 1; i <= theCurves.Length(); i++)
112 {
51740958 113 Handle(Geom_BSplineCurve) Cres = Handle(Geom_BSplineCurve)::DownCast(theCurves(i));
114 Cres->SetKnots(NewKnots);
93442c6f 115 }
116}
7fd59977 117
118//=======================================================================
119//function : GeomFill_Profiler
120//purpose :
121//=======================================================================
122
123GeomFill_Profiler::GeomFill_Profiler()
124{
125 myIsDone = Standard_False;
126 myIsPeriodic = Standard_True;
127}
128
129
130//=======================================================================
131
6da30ff1 132GeomFill_Profiler::~GeomFill_Profiler()
133{
134}
7fd59977 135
136
137//=======================================================================
138//function : AddCurve
139//purpose :
140//=======================================================================
141
142void GeomFill_Profiler::AddCurve(const Handle(Geom_Curve)& Curve)
143{
144 Handle(Geom_Curve) C;
145 //// modified by jgv, 19.01.05 for OCC7354 ////
146 Handle(Geom_Curve) theCurve = Curve;
147 if (theCurve->IsInstance(STANDARD_TYPE(Geom_TrimmedCurve)))
c5f3a425 148 theCurve = Handle(Geom_TrimmedCurve)::DownCast (theCurve)->BasisCurve();
7fd59977 149 if (theCurve->IsKind(STANDARD_TYPE(Geom_Conic)))
150 {
151 GeomConvert_ApproxCurve appr(Curve, Precision::Confusion(), GeomAbs_C1, 16, 14);
152 if (appr.HasResult())
153 C = appr.Curve();
154 }
155 if (C.IsNull())
156 C = GeomConvert::CurveToBSplineCurve(Curve);
157 /*
158 if ( Curve->IsKind(STANDARD_TYPE(Geom_BSplineCurve))) {
159 C = Handle(Geom_Curve)::DownCast(Curve->Copy());
160 }
161 else {
162 C = GeomConvert::CurveToBSplineCurve(Curve,Convert_QuasiAngular);
163 }
164 */
165 ///////////////////////////////////////////////
166
167 mySequence.Append( C);
168
169 if ( myIsPeriodic && !C->IsPeriodic())
170 myIsPeriodic = Standard_False;
171}
172
173
174//=======================================================================
175//function : Perform
176//purpose :
177//=======================================================================
178
179void GeomFill_Profiler::Perform(const Standard_Real PTol)
180{
181 Standard_Integer i;
182// Standard_Integer myDegree = 0, myNbPoles = 0;
183 Standard_Integer myDegree = 0;
184 Handle(Geom_BSplineCurve) C;
185 Standard_Real U1, U2, UFirst=0, ULast=0;
186 Standard_Real EcartMax = 0.;
187
188 for ( i = 1; i <= mySequence.Length(); i++) {
189 C = Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
190
191 // si non periodique, il faut deperiodiser toutes les courbes
192 // on les segmente ensuite pour assurer K(1) et K(n) de multiplicite
193 // degre + 1
194
195 U2 = C->Knot(C->LastUKnotIndex());
196 U1 = C->Knot(C->FirstUKnotIndex());
197
198 if ( !myIsPeriodic && C->IsPeriodic()) {
199 C->SetNotPeriodic();
200 C->Segment( U1, U2);
201 }
202
203 // evaluate the max degree
204 myDegree = Max( myDegree, C->Degree());
205
206 // Calcul de Max ( Ufin - Udeb) sur l ensemble des courbes.
207 if ( ( U2 - U1) > EcartMax) {
208 EcartMax = U2 - U1;
209 UFirst = U1;
210 ULast = U2;
211 }
212 }
213
214 // increase the degree of the curves to my degree
215 // reparametrize them in the range U1, U2.
216 for ( i = 1; i <= mySequence.Length(); i++) {
217 C = Handle(Geom_BSplineCurve)::DownCast(mySequence(i));
218
219 C->IncreaseDegree( myDegree);
220
221 TColStd_Array1OfReal Knots(1,C->NbKnots());
222 C->Knots(Knots);
223 BSplCLib::Reparametrize(UFirst,ULast,Knots);
224 C->SetKnots(Knots);
225 }
7fd59977 226
93442c6f 227 TColGeom_SequenceOfCurve theCurves;
228 for (i = 1; i <= mySequence.Length(); i++)
229 theCurves.Append(Handle(Geom_Curve)::DownCast(mySequence(i)->Copy()));
7fd59977 230
93442c6f 231 UnifyByInsertingAllKnots(theCurves, PTol);
7fd59977 232
93442c6f 233 Standard_Boolean Unified = Standard_True;
234 Standard_Integer theNbKnots = (Handle(Geom_BSplineCurve)::DownCast(theCurves(1)))->NbKnots();
235 for (i = 2; i <= theCurves.Length(); i++)
236 if ((Handle(Geom_BSplineCurve)::DownCast(theCurves(i)))->NbKnots() != theNbKnots)
237 {
238 Unified = Standard_False;
239 break;
7fd59977 240 }
93442c6f 241
242 if (Unified)
243 mySequence = theCurves;
244 else
245 UnifyBySettingMiddleKnots(mySequence);
7fd59977 246
247 myIsDone = Standard_True;
248}
249
250
251//=======================================================================
252//function : Degree
253//purpose :
254//=======================================================================
255
256Standard_Integer GeomFill_Profiler::Degree() const
257{
258 if ( !myIsDone)
9775fa61 259 throw StdFail_NotDone("GeomFill_Profiler::Degree");
7fd59977 260
261 Handle(Geom_BSplineCurve) C =
262 Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
263 return C->Degree();
264}
265
266
267//=======================================================================
268//function : NbPoles
269//purpose :
270//=======================================================================
271
272Standard_Integer GeomFill_Profiler::NbPoles() const
273{
274 if ( !myIsDone)
9775fa61 275 throw StdFail_NotDone("GeomFill_Profiler::Degree");
7fd59977 276
277 Handle(Geom_BSplineCurve) C =
278 Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
279 return C->NbPoles();
280}
281
282
283//=======================================================================
284//function : Poles
285//purpose :
286//=======================================================================
287
288void GeomFill_Profiler::Poles(const Standard_Integer Index,
289 TColgp_Array1OfPnt& Poles) const
290{
291 if ( !myIsDone)
9775fa61 292 throw StdFail_NotDone("GeomFill_Profiler::Degree");
7fd59977 293
294 Standard_DomainError_Raise_if( Poles.Length() != NbPoles(),
295 "GeomFill_Profiler::Poles");
296 Standard_DomainError_Raise_if( Index < 1 || Index > mySequence.Length(),
297 "GeomFill_Profiler::Poles");
298
299 Handle(Geom_BSplineCurve) C =
300 Handle(Geom_BSplineCurve)::DownCast(mySequence(Index));
301
302 C->Poles(Poles);
303}
304
305
306//=======================================================================
307//function : Weights
308//purpose :
309//=======================================================================
310
311void GeomFill_Profiler::Weights(const Standard_Integer Index,
312 TColStd_Array1OfReal& Weights) const
313{
314 if ( !myIsDone)
9775fa61 315 throw StdFail_NotDone("GeomFill_Profiler::Degree");
7fd59977 316
317 Standard_DomainError_Raise_if( Weights.Length() != NbPoles(),
318 "GeomFill_Profiler::Weights");
319 Standard_DomainError_Raise_if( Index < 1 || Index > mySequence.Length(),
320 "GeomFill_Profiler::Weights");
321
322 Handle(Geom_BSplineCurve) C =
323 Handle(Geom_BSplineCurve)::DownCast(mySequence(Index));
324
325 C->Weights(Weights);
326}
327
328
329//=======================================================================
330//function : NbKnots
331//purpose :
332//=======================================================================
333
334Standard_Integer GeomFill_Profiler::NbKnots() const
335{
336 if ( !myIsDone)
9775fa61 337 throw StdFail_NotDone("GeomFill_Profiler::Degree");
7fd59977 338
339 Handle(Geom_BSplineCurve) C =
340 Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
341
342 return C->NbKnots();
343}
344
345
346//=======================================================================
347//function : KnotsAndMults
348//purpose :
349//=======================================================================
350
351void GeomFill_Profiler::KnotsAndMults(TColStd_Array1OfReal& Knots,
352 TColStd_Array1OfInteger& Mults ) const
353{
354 if ( !myIsDone)
9775fa61 355 throw StdFail_NotDone("GeomFill_Profiler::Degree");
7fd59977 356
357#ifndef No_Exception
358 Standard_Integer n = NbKnots();
359#endif
360 Standard_DomainError_Raise_if( Knots.Length() != n || Mults.Length() != n,
361 "GeomFill_Profiler::KnotsAndMults");
362
363 Handle(Geom_BSplineCurve) C =
364 Handle(Geom_BSplineCurve)::DownCast(mySequence(1));
365
366 C->Knots(Knots);
367 C->Multiplicities(Mults);
368}
369
370