0024428: Implementation of LGPL license
[occt.git] / src / Convert / Convert_SphereToBSplineSurface.cxx
CommitLineData
b311480e 1// Copyright (c) 1995-1999 Matra Datavision
973c2be1 2// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 3//
973c2be1 4// This file is part of Open CASCADE Technology software library.
b311480e 5//
973c2be1 6// This library is free software; you can redistribute it and / or modify it
7// under the terms of the GNU Lesser General Public version 2.1 as published
8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
b311480e 11//
973c2be1 12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
b311480e 14
7fd59977 15//JCV 16/10/91
16
17#include <Convert_SphereToBSplineSurface.ixx>
18
19#include <gp.hxx>
20#include <gp_Trsf.hxx>
21
22static const Standard_Integer TheUDegree = 2;
23static const Standard_Integer TheVDegree = 2;
24static const Standard_Integer MaxNbUKnots = 4;
25static const Standard_Integer MaxNbVKnots = 3;
26static const Standard_Integer MaxNbUPoles = 7;
27static const Standard_Integer MaxNbVPoles = 5;
28
29
30static void ComputePoles ( const Standard_Real R,
31 const Standard_Real U1,
32 const Standard_Real U2,
33 const Standard_Real V1,
34 const Standard_Real V2,
35 TColgp_Array2OfPnt& Poles)
36{
37 Standard_Real deltaU = U2 - U1;
38 Standard_Real deltaV = V2 - V1;
39
40 Standard_Integer i, j;
41
0d969553 42 // Number of spans : maximum opening = 150 degrees ( = PI / 1.2 rds)
7fd59977 43 Standard_Integer
c6541a0c 44 nbUSpans = (Standard_Integer)IntegerPart( 1.2 * deltaU / M_PI) + 1;
7fd59977 45 Standard_Integer
c6541a0c 46 nbVSpans = (Standard_Integer)IntegerPart( 1.2 * deltaV / M_PI) + 1;
7fd59977 47 Standard_Real AlfaU = deltaU / ( nbUSpans * 2);
48 Standard_Real AlfaV = deltaV / ( nbVSpans * 2);
49
50 Standard_Integer nbVP = 2 * nbVSpans + 1;
51
52 Standard_Real x[MaxNbVPoles];
53 Standard_Real z[MaxNbVPoles];
54
55 x[0] = R * Cos( V1);
56 z[0] = R * Sin( V1);
57
58 Standard_Real VStart = V1;
59 for ( i = 1; i <= nbVSpans; i++) {
60 x[2*i-1] = R * Cos( VStart + AlfaV) / Cos( AlfaV);
61 z[2*i-1] = R * Sin( VStart + AlfaV) / Cos( AlfaV);
62 x[2*i] = R * Cos( VStart + 2 * AlfaV);
63 z[2*i] = R * Sin( VStart + 2 * AlfaV);
64 VStart += 2*AlfaV;
65 }
66
67 Standard_Real UStart = U1;
68 for ( j = 0; j <= nbVP-1; j++) {
69 Poles( 1, j+1) = gp_Pnt(x[j]*Cos(UStart),x[j]*Sin(UStart),z[j]);
70 }
71
72 for ( i = 1; i <= nbUSpans; i++) {
73 for ( j = 0; j<= nbVP-1; j++) {
74 Poles( 2*i, j+1) = gp_Pnt( x[j] * Cos(UStart+AlfaU) / Cos(AlfaU),
75 x[j] * Sin(UStart+AlfaU) / Cos(AlfaU),
76 z[j] );
77 Poles(2*i+1,j+1) = gp_Pnt( x[j] * Cos(UStart+2*AlfaU),
78 x[j] * Sin(UStart+2*AlfaU),
79 z[j] );
80 }
81 UStart += 2*AlfaU;
82 }
83}
84
85//=======================================================================
86//function : Convert_SphereToBSplineSurface
87//purpose :
88//=======================================================================
89
90Convert_SphereToBSplineSurface::Convert_SphereToBSplineSurface
91 (const gp_Sphere& Sph,
92 const Standard_Real U1 ,
93 const Standard_Real U2 ,
94 const Standard_Real V1 ,
95 const Standard_Real V2 )
96: Convert_ElementarySurfaceToBSplineSurface (MaxNbUPoles, MaxNbVPoles,
97 MaxNbUKnots, MaxNbVKnots,
98 TheUDegree , TheVDegree)
99{
100 Standard_Real deltaU = U2 - U1;
101 Standard_Real deltaV = V2 - V1;
c6541a0c
D
102 Standard_DomainError_Raise_if( (deltaU>2*M_PI) || (deltaU<0.) ||
103 (V1 < -M_PI/2.0) || (V2 > M_PI/2),
7fd59977 104 "Convert_SphereToBSplineSurface");
105
106 isuperiodic = Standard_False;
107 isvperiodic = Standard_False;
108
109 Standard_Integer i,j;
0d969553 110 // construction of the sphere in the reference mark xOy.
7fd59977 111
0d969553 112 // Number of spans : maximum opening = 150 degrees ( = PI / 1.2 rds)
7fd59977 113 Standard_Integer
c6541a0c 114 nbUSpans = (Standard_Integer)IntegerPart( 1.2 * deltaU / M_PI) + 1;
7fd59977 115 Standard_Integer
c6541a0c 116 nbVSpans = (Standard_Integer)IntegerPart( 1.2 * deltaV / M_PI) + 1;
7fd59977 117 Standard_Real AlfaU = deltaU / ( nbUSpans * 2);
118 Standard_Real AlfaV = deltaV / ( nbVSpans * 2);
119
120 nbUPoles = 2 * nbUSpans + 1;
121 nbVPoles = 2 * nbVSpans + 1;
122 nbUKnots = nbUSpans + 1;
123 nbVKnots = nbVSpans + 1;
124
125 Standard_Real R = Sph.Radius();
126
127 ComputePoles( R, U1, U2, V1, V2, poles);
128
129 for ( i = 1; i<= nbUKnots; i++) {
130 uknots(i) = U1 + (i-1) * 2 * AlfaU;
131 umults(i) = 2;
132 }
133 umults(1)++; umults(nbUKnots)++;
134 for ( i = 1; i<= nbVKnots; i++) {
135 vknots(i) = V1 + (i-1) * 2 * AlfaV;
136 vmults(i) = 2;
137 }
138 vmults(1)++; vmults(nbVKnots)++;
139
140
0d969553
Y
141 // Replace the bspline in the reference of the sphere.
142 // and calculate the weight of the bspline.
7fd59977 143 Standard_Real W1, W2;
144 gp_Trsf Trsf;
145 Trsf.SetTransformation( Sph.Position(), gp::XOY());
146
147 for ( i = 1; i <= nbUPoles; i++) {
148 if ( i % 2 == 0) W1 = Cos(AlfaU);
149 else W1 = 1.;
150
151 for ( j = 1; j <= nbVPoles; j++) {
152 if ( j % 2 == 0) W2 = Cos(AlfaV);
153 else W2 = 1.;
154
155 weights( i, j) = W1 * W2;
156 poles( i, j).Transform( Trsf);
157 }
158 }
159}
160
161
162//=======================================================================
163//function : Convert_SphereToBSplineSurface
164//purpose :
165//=======================================================================
166
167Convert_SphereToBSplineSurface::Convert_SphereToBSplineSurface
168 (const gp_Sphere& Sph ,
169 const Standard_Real Param1,
170 const Standard_Real Param2,
171 const Standard_Boolean UTrim )
172: Convert_ElementarySurfaceToBSplineSurface (MaxNbUPoles, MaxNbVPoles,
173 MaxNbUKnots, MaxNbVKnots,
174 TheUDegree , TheVDegree)
175{
176#ifndef No_Exception
177 Standard_Real delta = Param2 - Param1;
178#endif
c6541a0c 179 Standard_DomainError_Raise_if( (delta>2*M_PI) || (delta<0.),
7fd59977 180 "Convert_SphereToBSplineSurface");
181
182 Standard_Integer i, j;
183 Standard_Real deltaU, deltaV;
184
185 isuperiodic = !UTrim;
186 isvperiodic = Standard_False;
187
188 Standard_Real R = Sph.Radius();
189
190 Standard_Real W1, W2, CosU, CosV;
191
192 if ( isuperiodic) {
c6541a0c 193 ComputePoles(R, 0., 2.*M_PI, Param1, Param2, poles);
7fd59977 194
195 nbUPoles = 6;
196 nbUKnots = 4;
197
198 deltaV = Param2 - Param1;
199 Standard_Integer
c6541a0c 200 nbVSpans = (Standard_Integer)IntegerPart( 1.2 * deltaV / M_PI) + 1;
7fd59977 201 Standard_Real AlfaV = deltaV / ( nbVSpans * 2);
202 nbVPoles = 2 * nbVSpans + 1;
203 nbVKnots = nbVSpans + 1;
204
205 for ( i = 1; i <= nbUKnots; i++) {
c6541a0c 206 uknots(i) = ( i-1) * 2. * M_PI /3.;
7fd59977 207 umults(i) = 2;
208 }
209 for ( i = 1; i <= nbVKnots; i++) {
210 vknots(i) = Param1 + (i-1) * 2 * AlfaV;
211 vmults(i) = 2;
212 }
213 vmults(1)++; vmults(nbVKnots)++;
214
215 CosU = 0.5; // = Cos(pi /3)
216 CosV = Cos(AlfaV);
217 }
218 else {
c6541a0c 219 ComputePoles(R, Param1, Param2, -M_PI/2., M_PI/2., poles);
7fd59977 220
221 nbVPoles = 5;
222 nbVKnots = 3;
223
224 deltaU = Param2 - Param1;
225 Standard_Integer
c6541a0c 226 nbUSpans = (Standard_Integer)IntegerPart( 1.2 * deltaU / M_PI) + 1;
7fd59977 227 Standard_Real AlfaU = deltaU / ( nbUSpans * 2);
228 nbUPoles = 2 * nbUSpans + 1;
229 nbUKnots = nbUSpans + 1;
230
c6541a0c 231 vknots(1) = -M_PI/2.; vmults(1) = 3;
7fd59977 232 vknots(2) = 0.; vmults(2) = 2;
c6541a0c 233 vknots(3) = M_PI/2.; vmults(3) = 3;
7fd59977 234 for ( i = 1; i <= nbUKnots; i++) {
235 uknots(i) = Param1 + (i-1) * 2 * AlfaU;
236 umults(i) = 2;
237 }
238 umults(1)++; umults(nbUKnots)++;
239
240 CosV = 0.5; // = Cos(pi /3)
241 CosU = Cos(AlfaU);
242 }
243
0d969553
Y
244 // Replace the bspline in the mark of the sphere.
245 // and calculate the weight of bspline.
7fd59977 246 gp_Trsf Trsf;
247 Trsf.SetTransformation( Sph.Position(), gp::XOY());
248
249 for ( i = 1; i <= nbUPoles; i++) {
250 if ( i % 2 == 0) W1 = CosU;
251 else W1 = 1.;
252
253 for ( j = 1; j <= nbVPoles; j++) {
254 if ( j % 2 == 0) W2 = CosV;
255 else W2 = 1.;
256
257 weights( i, j) = W1 * W2;
258 poles( i, j).Transform( Trsf);
259 }
260 }
261}
262
263
264//=======================================================================
265//function : Convert_SphereToBSplineSurface
266//purpose :
267//=======================================================================
268
269Convert_SphereToBSplineSurface::Convert_SphereToBSplineSurface
270 (const gp_Sphere& Sph)
271: Convert_ElementarySurfaceToBSplineSurface (MaxNbUPoles, MaxNbVPoles,
272 MaxNbUKnots, MaxNbVKnots,
273 TheUDegree , TheVDegree)
274{
275 isuperiodic = Standard_True;
276 isvperiodic = Standard_False;
277
278 Standard_Real W1, W2;
279 Standard_Integer i, j;
280
281 nbUPoles = 6;
282 nbVPoles = 5;
283 nbUKnots = 4;
284 nbVKnots = 3;
285
0d969553 286 // Construction of the sphere in the reference mark xOy.
7fd59977 287
288 Standard_Real R = Sph.Radius();
289
c6541a0c 290 ComputePoles( R, 0., 2.*M_PI, -M_PI/2., M_PI/2., poles);
7fd59977 291
292 uknots( 1) = 0.;
c6541a0c
D
293 uknots( 2) = 2. * M_PI / 3.;
294 uknots( 3) = 4. * M_PI / 3.;
295 uknots( 4) = 2. * M_PI;
296 vknots( 1) = -M_PI/2.;
7fd59977 297 vknots( 2) = 0.;
c6541a0c 298 vknots( 3) = M_PI/2.;
7fd59977 299 for ( i = 1; i <= 4; i++) {
300 umults( i) = 2;
301 }
302 vmults(1) = vmults(3) = 3;
303 vmults(2) = 2;
304
0d969553
Y
305 // Replace the bspline in the mark of the sphere.
306 // and calculate the weight of the bspline.
7fd59977 307 gp_Trsf Trsf;
308 Trsf.SetTransformation( Sph.Position(), gp::XOY());
309
310 for ( i = 1; i <= nbUPoles; i++) {
311 if ( i % 2 == 0) W1 = 0.5;
312 else W1 = 1.;
313
314 for ( j = 1; j <= nbVPoles; j++) {
315 if ( j % 2 == 0) W2 = Sqrt(2.) /2.;
316 else W2 = 1.;
317
318 weights( i, j) = W1 * W2;
319 poles( i, j).Transform( Trsf);
320 }
321 }
322}
323