0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / Convert / Convert_SphereToBSplineSurface.cxx
1 // Copyright (c) 1995-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
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
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.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 //JCV 16/10/91
16
17 #include <Convert_SphereToBSplineSurface.hxx>
18 #include <gp.hxx>
19 #include <gp_Sphere.hxx>
20 #include <gp_Trsf.hxx>
21 #include <Standard_DomainError.hxx>
22
23 static const Standard_Integer TheUDegree  = 2;
24 static const Standard_Integer TheVDegree  = 2;
25 static const Standard_Integer MaxNbUKnots = 4;
26 static const Standard_Integer MaxNbVKnots = 3;
27 static const Standard_Integer MaxNbUPoles = 7;
28 static const Standard_Integer MaxNbVPoles = 5;
29
30
31 static 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
43   // Number of spans : maximum opening = 150 degrees ( = PI / 1.2 rds)
44   Standard_Integer 
45     nbUSpans = (Standard_Integer)IntegerPart( 1.2 * deltaU / M_PI) + 1;
46   Standard_Integer  
47     nbVSpans = (Standard_Integer)IntegerPart( 1.2 * deltaV / M_PI) + 1;
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
91 Convert_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;
103   Standard_DomainError_Raise_if( (deltaU>2*M_PI) || (deltaU<0.) ||
104                                  (V1 < -M_PI/2.0) || (V2 > M_PI/2),
105                                 "Convert_SphereToBSplineSurface");
106
107   isuperiodic = Standard_False;
108   isvperiodic = Standard_False;
109
110   Standard_Integer i,j;
111   // construction of the sphere in the reference mark xOy.
112
113   // Number of spans : maximum opening = 150 degrees ( = PI / 1.2 rds)
114   Standard_Integer 
115     nbUSpans = (Standard_Integer)IntegerPart( 1.2 * deltaU / M_PI) + 1;
116   Standard_Integer  
117     nbVSpans = (Standard_Integer)IntegerPart( 1.2 * deltaV / M_PI) + 1;
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
142   // Replace the bspline in the reference of the sphere.
143   // and calculate the weight of the bspline.
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
168 Convert_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
180   Standard_DomainError_Raise_if( (delta>2*M_PI) || (delta<0.),
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) {
194     ComputePoles(R, 0., 2.*M_PI, Param1, Param2, poles);
195     
196     nbUPoles = 6;
197     nbUKnots = 4;
198     
199     deltaV = Param2 - Param1;
200     Standard_Integer  
201       nbVSpans = (Standard_Integer)IntegerPart( 1.2 * deltaV / M_PI) + 1;
202     Standard_Real AlfaV = deltaV / ( nbVSpans * 2);
203     nbVPoles = 2 * nbVSpans + 1;
204     nbVKnots = nbVSpans + 1;
205     
206     for ( i = 1; i <= nbUKnots; i++) {
207       uknots(i) = ( i-1) * 2. * M_PI /3.;
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 {
220     ComputePoles(R, Param1, Param2, -M_PI/2., M_PI/2., poles);
221     
222     nbVPoles = 5;
223     nbVKnots = 3;
224     
225     deltaU = Param2 - Param1;
226     Standard_Integer  
227       nbUSpans = (Standard_Integer)IntegerPart( 1.2 * deltaU / M_PI) + 1;
228     Standard_Real AlfaU = deltaU / ( nbUSpans * 2);
229     nbUPoles = 2 * nbUSpans + 1;
230     nbUKnots = nbUSpans + 1;
231     
232     vknots(1) = -M_PI/2.;  vmults(1) = 3;
233     vknots(2) =     0.;  vmults(2) = 2;
234     vknots(3) =  M_PI/2.;  vmults(3) = 3;
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
245   // Replace the bspline in the mark of the sphere.
246   // and calculate the weight of bspline.
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
270 Convert_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
287   // Construction of the sphere in the reference mark xOy.
288   
289   Standard_Real R = Sph.Radius();
290
291   ComputePoles( R, 0., 2.*M_PI, -M_PI/2., M_PI/2., poles);
292
293   uknots( 1) = 0.;
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.;
298   vknots( 2) =     0.;
299   vknots( 3) =  M_PI/2.;
300   for ( i = 1; i <= 4; i++) {
301     umults( i) = 2;
302   }
303   vmults(1) = vmults(3) = 3;
304   vmults(2) = 2;
305
306   // Replace the bspline in the mark of the sphere.
307   // and calculate the weight of the bspline.
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