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