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