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