0024166: Unable to create file with "Save" menu of voxeldemo Qt sample
[occt.git] / src / Convert / Convert_CompBezierCurvesToBSplineCurve.cxx
CommitLineData
b311480e 1// Created on: 1993-10-20
2// Created by: Bruno DUMORTIER
3// Copyright (c) 1993-1999 Matra Datavision
4// Copyright (c) 1999-2012 OPEN CASCADE SAS
5//
6// The content of this file is subject to the Open CASCADE Technology Public
7// License Version 6.5 (the "License"). You may not use the content of this file
8// except in compliance with the License. Please obtain a copy of the License
9// at http://www.opencascade.org and read it completely before using this file.
10//
11// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13//
14// The Original Code and all software distributed under the License is
15// distributed on an "AS IS" basis, without warranty of any kind, and the
16// Initial Developer hereby disclaims all such warranties, including without
17// limitation, any warranties of merchantability, fitness for a particular
18// purpose or non-infringement. Please see the License for the specific terms
19// and conditions governing the rights and limitations under the License.
20
0d969553 21
7fd59977 22
23#include <Convert_CompBezierCurvesToBSplineCurve.ixx>
24
25#include <Precision.hxx>
26#include <BSplCLib.hxx>
27#include <PLib.hxx>
28#include <gp_Pnt.hxx>
29#include <gp.hxx>
30#include <gp_Vec.hxx>
31#include <TColgp_HArray1OfPnt.hxx>
32
33
34//=======================================================================
35//function : Convert_CompBezierCurvesToBSplineCurve
36//purpose :
37//=======================================================================
38
39
40Convert_CompBezierCurvesToBSplineCurve::
41Convert_CompBezierCurvesToBSplineCurve(
42 const Standard_Real AngularTolerance) :
43 myAngular(AngularTolerance),
44 myDone(Standard_False)
45{
46}
47
48
49//=======================================================================
50//function : AddCurve
51//purpose :
52//=======================================================================
53
54void Convert_CompBezierCurvesToBSplineCurve::AddCurve
55 (const TColgp_Array1OfPnt& Poles)
56{
57 if ( !mySequence.IsEmpty()) {
58 gp_Pnt P1,P2;
59 P1 = mySequence.Last()->Value(mySequence.Last()->Upper());
60 P2 = Poles(Poles.Lower());
61
62 // NYI
63 if ( !P1.IsEqual(P2,Precision::Confusion()))
64 cout << "Convert_CompBezierCurvesToBSplineCurve::Addcurve" << endl;;
65 }
66 myDone = Standard_False;
67 Handle(TColgp_HArray1OfPnt) HPoles =
68 new TColgp_HArray1OfPnt(Poles.Lower(),Poles.Upper());
69 HPoles->ChangeArray1() = Poles;
70 mySequence.Append(HPoles);
71}
72
73
74//=======================================================================
75//function : Degree
76//purpose :
77//=======================================================================
78
79Standard_Integer Convert_CompBezierCurvesToBSplineCurve::Degree() const
80{
81 return myDegree;
82}
83
84
85//=======================================================================
86//function : NbPoles
87//purpose :
88//=======================================================================
89
90Standard_Integer Convert_CompBezierCurvesToBSplineCurve::NbPoles() const
91{
92 return CurvePoles.Length();
93}
94
95
96//=======================================================================
97//function : Poles
98//purpose :
99//=======================================================================
100
101void Convert_CompBezierCurvesToBSplineCurve::Poles
102 (TColgp_Array1OfPnt& Poles) const
103{
104 Standard_Integer i, Lower = Poles.Lower(), Upper = Poles.Upper();
105 Standard_Integer k = 1;
106 for (i = Lower; i <= Upper; i++) {
107 Poles(i) = CurvePoles(k++);
108 }
109}
110
111
112//=======================================================================
113//function : NbKnots
114//purpose :
115//=======================================================================
116
117Standard_Integer Convert_CompBezierCurvesToBSplineCurve::NbKnots() const
118{
119 return CurveKnots.Length();
120}
121
122
123//=======================================================================
124//function : KnotsAndMults
125//purpose :
126//=======================================================================
127
128void Convert_CompBezierCurvesToBSplineCurve::KnotsAndMults
129 (TColStd_Array1OfReal& Knots,
130 TColStd_Array1OfInteger& Mults ) const
131{
132 Standard_Integer i, LowerK = Knots.Lower(), UpperK = Knots.Upper();
133 Standard_Integer LowerM = Mults.Lower(), UpperM = Mults.Upper();
134 Standard_Integer k = 1;
135 for (i = LowerK; i <= UpperK; i++) {
136 Knots(i) = CurveKnots(k++);
137 }
138 k = 1;
139 for (i = LowerM; i <= UpperM; i++) {
140 Mults(i) = KnotsMultiplicities(k++);
141 }
142}
143
144
145
146//=======================================================================
147//function : Perform
148//purpose :
149//=======================================================================
150
151void Convert_CompBezierCurvesToBSplineCurve::Perform()
152{
153 myDone = Standard_True;
154 CurvePoles.Clear();
155 CurveKnots.Clear();
156 KnotsMultiplicities.Clear();
157 Standard_Integer LowerI = 1;
158 Standard_Integer UpperI = mySequence.Length();
159 Standard_Integer NbrCurv = UpperI-LowerI+1;
160// Standard_Integer NbKnotsSpl = NbrCurv + 1 ;
161 TColStd_Array1OfReal CurveKnVals (1,NbrCurv);
162
163 Standard_Integer i;
164 myDegree = 0;
165 for ( i = 1; i <= mySequence.Length(); i++) {
166 myDegree = Max( myDegree, (mySequence(i))->Length() -1);
167 }
168
169 Standard_Real D1, D2, Lambda, Det=0;
170 gp_Pnt P1, P2, P3;
171 Standard_Integer Deg, Inc, MaxDegree = myDegree;
172 TColgp_Array1OfPnt Points(1, myDegree+1);
173
174 for (i = LowerI ; i <= UpperI ; i++) {
0d969553 175 // 1- Raise the Bezier curve to the maximum degree.
7fd59977 176 Deg = mySequence(i)->Length()-1;
177 Inc = myDegree - Deg;
178 if ( Inc > 0) {
179 BSplCLib::IncreaseDegree(myDegree,
180 mySequence(i)->Array1(), PLib::NoWeights(),
181 Points, PLib::NoWeights());
182 }
183 else {
184 Points = mySequence(i)->Array1();
185 }
186
0d969553 187 // 2- Process the node of junction between 2 Bezier curves.
7fd59977 188 if (i == LowerI) {
0d969553 189 // Processing of the initial node of the BSpline.
7fd59977 190 for (Standard_Integer j = 1 ; j <= MaxDegree ; j++) {
191 CurvePoles.Append(Points(j));
192 }
0d969553 193 CurveKnVals(1) = 1.; // To begin the series.
7fd59977 194 KnotsMultiplicities.Append(MaxDegree+1);
195 Det = 1.;
196 }
197
198
199 if (i != LowerI) {
200 P2 = Points(1);
201 P3 = Points(2);
202 gp_Vec V1(P1, P2), V2(P2, P3);
203 D1 = P1.SquareDistance(P2);
204 D2 = P3.SquareDistance(P2);
205 Lambda = Sqrt(D2/D1);
206// cout << "D1, D2, Lambda : " << D1 << " " << D2 << " " << Lambda << endl;
207
0d969553
Y
208 // Processing of the tangency between Bezier and the previous.
209 // This allows to guarantee at least a C1 continuity if the tangents are
210 // coherent.
7fd59977 211
212 if (V1.Magnitude() > gp::Resolution() &&
213 V2.Magnitude() > gp::Resolution() &&
214 V1.IsParallel(V2, myAngular )) {
215 if(CurveKnVals(i-1) * Lambda > 10. * Epsilon(Det)) {
216 KnotsMultiplicities.Append(MaxDegree-1);
217 CurveKnVals(i) = CurveKnVals(i-1) * Lambda;
218 Det += CurveKnVals(i);
219 }
220 else {
221 CurvePoles.Append(Points(1));
222 KnotsMultiplicities.Append(MaxDegree);
223 CurveKnVals(i) = 1.0 ;
224 Det += CurveKnVals(i) ;
225 }
226 }
227 else {
228 CurvePoles.Append(Points(1));
229 KnotsMultiplicities.Append(MaxDegree);
230 CurveKnVals(i) = 1.0 ;
231 Det += CurveKnVals(i) ;
232 }
233
0d969553 234 // Store the poles.
7fd59977 235 for (Standard_Integer j = 2 ; j <= MaxDegree ; j++) {
236 CurvePoles.Append(Points(j));
237 }
238
239 }
240
241
242 if (i == UpperI) {
0d969553 243 // Processing of the end node of the BSpline.
7fd59977 244 CurvePoles.Append(Points(MaxDegree+1));
245 KnotsMultiplicities.Append(MaxDegree+1);
246 }
247 P1 = Points(MaxDegree);
248 }
249
0d969553 250 // Correct nodal values to make them variable within [0.,1.].
7fd59977 251 CurveKnots.Append(0.0);
252// cout << "Convert : Det = " << Det << endl;
253 for (i = 2 ; i <= NbrCurv ; i++) {
254 CurveKnots.Append(CurveKnots(i-1) + (CurveKnVals(i-1)/Det));
255 }
256 CurveKnots.Append(1.0);
257}
258
259