0026042: OCCT won't work with the latest Xcode
[occt.git] / src / ShapeConstruct / ShapeConstruct_CompBezierCurvesToBSplineCurve.cxx
CommitLineData
b311480e 1// Created on: 1993-10-20
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1993-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.
b311480e 16
7fd59977 17// modified 25/06/1996 PMN : Ajout d'une tolerance Angulaire dans le
18// constructeur pour le test de continuite G1 (1 Radians c'etait trop
19// cf BUG PRO4481)
20//rln 20.06.99 work-around
21
7fd59977 22#include <BSplCLib.hxx>
7fd59977 23#include <gp.hxx>
42cf5bc1 24#include <gp_Pnt.hxx>
7fd59977 25#include <gp_Vec.hxx>
42cf5bc1 26#include <PLib.hxx>
27#include <Precision.hxx>
28#include <ShapeConstruct_CompBezierCurvesToBSplineCurve.hxx>
29#include <Standard_ConstructionError.hxx>
7fd59977 30#include <TColgp_HArray1OfPnt.hxx>
31
7fd59977 32//=======================================================================
33//function : ShapeConstruct_CompBezierCurvesToBSplineCurve
34//purpose :
35//=======================================================================
7fd59977 36ShapeConstruct_CompBezierCurvesToBSplineCurve::
37ShapeConstruct_CompBezierCurvesToBSplineCurve(
38 const Standard_Real AngularTolerance) :
39 myAngular(AngularTolerance),
40 myDone(Standard_False)
41
42{
43}
44
45
46//=======================================================================
47//function : AddCurve
48//purpose :
49//=======================================================================
50
51void ShapeConstruct_CompBezierCurvesToBSplineCurve::AddCurve
52 (const TColgp_Array1OfPnt& Poles)
53{
54 if ( !mySequence.IsEmpty()) {
55 gp_Pnt P1,P2;
56 P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
57 P2 = Poles(Poles.Lower());
58
59 // NYI
60// Standard_ConstructionError_Raise_if
61// ( !P1.IsEqual(P2,Precision::Confusion()),
62// "ShapeConstruct_CompBezierCurvesToBSplineCurve::Addcurve");
63 }
64 myDone = Standard_False;
65 Handle(TColgp_HArray1OfPnt) HPoles =
66 new TColgp_HArray1OfPnt(Poles.Lower(),Poles.Upper());
67 HPoles->ChangeArray1() = Poles;
68 mySequence.Append(HPoles);
69}
70
71
72//=======================================================================
73//function : Degree
74//purpose :
75//=======================================================================
76
77Standard_Integer ShapeConstruct_CompBezierCurvesToBSplineCurve::Degree() const
78{
79 return myDegree;
80}
81
82
83//=======================================================================
84//function : NbPoles
85//purpose :
86//=======================================================================
87
88Standard_Integer ShapeConstruct_CompBezierCurvesToBSplineCurve::NbPoles() const
89{
90 return CurvePoles.Length();
91}
92
93
94//=======================================================================
95//function : Poles
96//purpose :
97//=======================================================================
98
99void ShapeConstruct_CompBezierCurvesToBSplineCurve::Poles
100 (TColgp_Array1OfPnt& Poles) const
101{
102 Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper();
103 Standard_Integer k = 1;
104 for (i = Lower; i <= Upper; i++) {
105 Poles(i) = CurvePoles(k++);
106 }
107}
108
109
110//=======================================================================
111//function : NbKnots
112//purpose :
113//=======================================================================
114
115Standard_Integer ShapeConstruct_CompBezierCurvesToBSplineCurve::NbKnots() const
116{
117 return CurveKnots.Length();
118}
119
120
121//=======================================================================
122//function : KnotsAndMults
123//purpose :
124//=======================================================================
125
126void ShapeConstruct_CompBezierCurvesToBSplineCurve::KnotsAndMults
127 (TColStd_Array1OfReal& Knots,
128 TColStd_Array1OfInteger& Mults ) const
129{
130 Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper();
131 Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper();
132 Standard_Integer k = 1;
133 for (i = LowerK; i <= UpperK; i++) {
134 Knots(i) = CurveKnots(k++);
135 }
136 k = 1;
137 for (i = LowerM; i <= UpperM; i++) {
138 Mults(i) = KnotsMultiplicities(k++);
139 }
140}
141
142
143
144//=======================================================================
145//function : Perform
146//purpose :
147//=======================================================================
148
149void ShapeConstruct_CompBezierCurvesToBSplineCurve::Perform()
150{
151 myDone = Standard_True;
152 CurvePoles.Clear();
153 CurveKnots.Clear();
154 KnotsMultiplicities.Clear();
155 Standard_Integer LowerI = 1;
156 Standard_Integer UpperI = mySequence.Length();
157 Standard_Integer NbrCurv = UpperI-LowerI+1;
158
159 TColStd_Array1OfReal CurveKnVals (1,NbrCurv);
160
161 Standard_Integer i;
162 myDegree = 0;
163 for ( i = 1; i <= mySequence.Length(); i++) {
164 myDegree = Max( myDegree, (mySequence(i))->Length() -1);
165 }
166
167 Standard_Real D1, D2, Lambda, Det=0.;
168 gp_Pnt P1, P2, P3;
169 Standard_Integer Deg, Inc, MaxDegree = myDegree;
170 TColgp_Array1OfPnt Points(1, myDegree+1);
171
172 for (i = LowerI ; i <= UpperI ; i++) {
173 // 1- Elever la courbe de Bezier au degre maximum.
174 Deg = mySequence(i)->Length()-1;
175 Inc = myDegree - Deg;
176 if ( Inc > 0) {
177 BSplCLib::IncreaseDegree(myDegree,
0e14656b 178 mySequence(i)->Array1(), BSplCLib::NoWeights(),
179 Points, BSplCLib::NoWeights());
7fd59977 180 }
181 else {
182 Points = mySequence(i)->Array1();
183 }
184
185 // 2- Traiter le noeud de jonction entre 2 courbes de Bezier.
186 if (i == LowerI) {
187 // Traitement du noeud initial de la BSpline.
188 for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
189 CurvePoles.Append(Points(j));
190 }
191 CurveKnVals(1) = 1.; // Pour amorcer la serie.
192 KnotsMultiplicities.Append(MaxDegree+1);
193 Det = 1.;
194 }
195
196
197 if (i != LowerI) {
198 P2 = Points(1);
199 P3 = Points(2);
200 gp_Vec V1(P1, P2), V2(P2, P3);
201 D1 = P1.SquareDistance(P2);
202 D2 = P3.SquareDistance(P2);
203 Lambda = Sqrt(D2/D1);
204
205
206 // Traitement de la tangence entre la Bezier et sa precedente.
207 // Ceci permet d''assurer au moins une continuite C1 si
208 // les tangentes sont coherentes.
209
210 if (V1.Magnitude() > gp::Resolution() &&
211 V2.Magnitude() > gp::Resolution() &&
212 V1.IsParallel(V2, myAngular ) &&
213 MaxDegree > 1) {//rln 20.06.99 work-around
214 KnotsMultiplicities.Append(MaxDegree-1);
215 CurveKnVals(i) = CurveKnVals(i-1) * Lambda;
216 Det += CurveKnVals(i);
217
218 }
219 else {
220 CurvePoles.Append(Points(1));
221 KnotsMultiplicities.Append(MaxDegree);
222 CurveKnVals(i) = 1.0e0 ;
223 Det += CurveKnVals(i) ;
224 }
225
226 // Stocker les poles.
227 for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) {
228 CurvePoles.Append(Points(j));
229 }
230
231 }
232
233
234 if (i == UpperI) {
235 // Traitement du noeud terminal de la BSpline.
236 CurvePoles.Append(Points(MaxDegree+1));
237 KnotsMultiplicities.Append(MaxDegree+1);
238 }
239 P1 = Points(MaxDegree);
240 }
241
242 // Corriger les valeurs nodales pour les faire varier dans [0.,1.].
243 CurveKnots.Append(0.0);
244 for (i = 2 ; i <= NbrCurv ; i++) {
245 CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det));
246 }
247 CurveKnots.Append(1.0);
248}
249
250