00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "stdafx.h"
00021
00022 #include <iostream>
00023
00024 #include "gul_types.h"
00025 #include "gul_vector.h"
00026 #include "gunu_basics.h"
00027
00028
00029 namespace gunu {
00030
00031 using gul::point1;
00032 using gul::point2;
00033 using gul::hpoint;
00034 using gul::hpoint1;
00035 using gul::hpoint2;
00036 using gul::set;
00037 using gul::euclid;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 template< class T >
00050 int FindSpan( const T u, const int n, const int p,
00051 const Ptr< T >& U )
00052 {
00053 int low,mid,high;
00054
00055
00056
00057 if( u == U[n+1] )
00058 {
00059 if( u == U[n+p+1] )
00060 return(n);
00061
00062 return( n+1 );
00063 }
00064
00065 low = p;
00066 high = n+1;
00067 mid = (low+high) / 2 ;
00068
00069 while( (u < U[mid]) || (u >= U[mid+1]) )
00070 {
00071 if( u < U[mid] )
00072 high = mid;
00073 else
00074 low = mid;
00075
00076 mid = (low+high) / 2;
00077 }
00078
00079 return(mid);
00080 }
00081
00082 template int FindSpan( const float u, const int n, const int p,
00083 const Ptr< float >& U );
00084 template int FindSpan( const double u, const int n, const int p,
00085 const Ptr< double >& U );
00086
00087
00088
00089
00090
00091
00092 template< class T >
00093 int FindSpanMultip( const T u, const int n, const int p,
00094 const Ptr< T >& U, int *s )
00095 {
00096 int l,low,mid,high;
00097
00098
00099
00100 if( u == U[n+1] )
00101 {
00102 if( u == U[n+p+1] )
00103 {
00104 *s = p + 1;
00105 return(n);
00106 }
00107
00108 l = n;
00109 while( l >= 0 )
00110 {
00111 if( U[l] != u ) break;
00112 l--;
00113 }
00114 *s = n+1 - l;
00115 return( n+1 );
00116 }
00117
00118 low = p;
00119 high = n+1;
00120 mid = (low+high) / 2 ;
00121
00122 while( (u < U[mid]) || (u >= U[mid+1]) )
00123 {
00124 if( u < U[mid] )
00125 high = mid;
00126 else
00127 low = mid;
00128
00129 mid = (low+high) / 2;
00130 }
00131
00132 l = mid;
00133 while( l >= 0 )
00134 {
00135 if( U[l] != u ) break;
00136 l--;
00137 }
00138 *s = mid - l;
00139
00140 return(mid);
00141 }
00142
00143 template int FindSpanMultip( const float u, const int n, const int p,
00144 const Ptr< float >& U, int *s );
00145 template int FindSpanMultip( const double u, const int n, const int p,
00146 const Ptr< double >& U, int *s );
00147
00148
00149
00150
00151
00152 template< class T >
00153 GULAPI bool ValidateKnotVec( const int n, const int p, const Ptr<T>& knt,
00154 bool& is_clamped, bool& is_normalized )
00155 {
00156 int m, multi, i;
00157 bool clamped0=false, clamped1=false;
00158 T u;
00159
00160 m = knt.nElems() - 1;
00161 if( m != n+p+1 ) return false;
00162
00163 u = knt[0];
00164 multi = 1;
00165 for( i = 1; i <= m; i++ )
00166 {
00167 if( knt[i] < knt[i-1] )
00168 return false;
00169
00170 if( knt[i] == u )
00171 multi++;
00172 else
00173 {
00174 u = knt[i];
00175 multi = 1;
00176 }
00177
00178 if( multi > p )
00179 {
00180 if( multi == p+1 )
00181 {
00182 if( i == p )
00183 {
00184 clamped0 = true;
00185 continue;
00186 }
00187 if( i == m )
00188 {
00189 clamped1 = true;
00190 continue;
00191 }
00192 }
00193 return false;
00194 }
00195 }
00196
00197 is_clamped = clamped0 && clamped1;
00198 is_normalized = ((knt[p] == (T)0.0) && (knt[n+1] == (T)1.0));
00199
00200 return true;
00201 }
00202
00203 template GULAPI bool ValidateKnotVec(
00204 const int n, const int p, const Ptr<float>& knt,
00205 bool& is_clamped, bool& is_normalized );
00206 template GULAPI bool ValidateKnotVec(
00207 const int n, const int p, const Ptr<double>& knt,
00208 bool& is_clamped, bool& is_normalized );
00209
00210
00211
00212
00213 template< class T >
00214 GULAPI T CalcBasisFunction( int p, int i, T u, int n, const Ptr<T>& U )
00215 {
00216 Ptr<T> N;
00217 int j,k;
00218 T saved,Uleft,Uright,temp;
00219
00220 N.reserve_pool(p+1);
00221
00222 if( ((i == 0) && (u == U[0])) ||
00223 ((i == n) && (u == U[n+1])) )
00224 return (T)1;
00225
00226 if( (u < U[i]) || (u >= U[i+p+1]) )
00227 return 0;
00228
00229
00230 for( j = 0; j <= p; j++ )
00231 {
00232 if( (u >= U[i+j]) && (u < U[i+j+1]) )
00233 N[j] = (T)1;
00234 else
00235 N[j] = (T)0;
00236 }
00237
00238
00239 for( k = 1; k <= p; k++ )
00240 {
00241 if( N[0] == (T)0 )
00242 saved = (T)0;
00243 else
00244 saved = ((u-U[i])*N[0])/(U[i+k]-U[i]);
00245
00246 for( j = 0; j < p-k+1; j++ )
00247 {
00248 Uleft = U[i+j+1];
00249 Uright = U[i+j+k+1];
00250
00251 if( N[j+1] == (T)0 )
00252 {
00253 N[j] = saved;
00254 saved = (T)0;
00255 }
00256 else
00257 {
00258 temp = N[j+1]/(Uright-Uleft);
00259 N[j] = saved + (Uright-u)*temp;
00260 saved = (u-Uleft)*temp;
00261 }
00262 }
00263 }
00264
00265 return N[0];
00266 }
00267
00268 template GULAPI float CalcBasisFunction(
00269 int p, int i, float u, int n, const Ptr<float>& U );
00270 template GULAPI double CalcBasisFunction(
00271 int p, int i, double u, int n, const Ptr<double>& U );
00272
00273
00274
00275
00276
00277 template< class T >
00278 void CalcBasisFunctions( const T u, const int i, const int p, const Ptr< T >& U,
00279 Ptr< T >& N )
00280 {
00281 Ptr< T > left,right;
00282 T saved,temp;
00283 int j,r;
00284
00285 left.reserve_place( reserve_stack(T,p+1), p+1 );
00286 right.reserve_place( reserve_stack(T,p+1), p+1 );
00287
00288 N[0] = 1.0;
00289
00290 for( j = 1; j <= p; j++ )
00291 {
00292 left[j] = u - U[i+1-j];
00293 right[j] = U[i+j] - u;
00294 saved = 0.0;
00295
00296 for( r = 0; r < j; r++ )
00297 {
00298 temp = N[r] / (right[r+1] + left[j-r]);
00299 N[r] = saved + (right[r+1] * temp);
00300 saved = left[j-r] * temp;
00301 }
00302
00303 N[j] = saved;
00304 }
00305 }
00306
00307 template void CalcBasisFunctions(
00308 const float u, const int i, const int p, const Ptr<float>& U,
00309 Ptr<float>& N );
00310 template void CalcBasisFunctions(
00311 const double u, const int i, const int p, const Ptr<double>& U,
00312 Ptr<double>& N );
00313
00314
00315
00316
00317
00318
00319 template< class T >
00320 GULAPI void UniformKnotVector( const int n, const int p, Ptr< T >& U )
00321 {
00322 int segs,i;
00323 T seglen;
00324
00325 for( i = 0; i <= p; i++ )
00326 {
00327 U[i] = 0.;
00328 U[n+1+i] = 1.;
00329 }
00330
00331 segs = n-p+1;
00332 seglen = (T)1. / ((T)segs);
00333 for( i = p+1; i <= n; i++ )
00334 {
00335
00336 U[i] = U[p] + seglen*(T)(i-p);
00337 }
00338 }
00339
00340 template GULAPI void UniformKnotVector( const int n, const int p, Ptr< float >& U );
00341 template GULAPI void UniformKnotVector( const int n, const int p, Ptr< double >& U );
00342
00343
00344
00345
00346 template< class T, class HP, class EP >
00347 GULAPI void CurvePoint(
00348 const T u, const int n, const int p, const Ptr< T >& U,
00349 const Ptr< HP >& Pw, EP *C )
00350 {
00351 Ptr< T > N;
00352 HP v1,h;
00353 int span,i;
00354
00355 N.reserve_place( reserve_stack(T,p+1), p+1 );
00356
00357 span = FindSpan( u, n, p, U );
00358 CalcBasisFunctions<T>( u, span, p, U, N );
00359
00360 set( h, (T)0.0 );
00361
00362 for( i = 0; i <= p; i++ )
00363 {
00364 v1 = N[i] * Pw[span-p+i];
00365 h = h + v1;
00366 }
00367 *C = euclid( h );
00368 }
00369
00370 template GULAPI void CurvePoint(
00371 const float u, const int n, const int p, const Ptr< float >& U,
00372 const Ptr< hpoint<float> >& Pw, point<float> *C );
00373 template GULAPI void CurvePoint(
00374 const double u, const int n, const int p, const Ptr< double >& U,
00375 const Ptr< hpoint<double> >& Pw, point<double> *C );
00376 template GULAPI void CurvePoint(
00377 const float u, const int n, const int p, const Ptr< float >& U,
00378 const Ptr< hpoint2<float> >& Pw, point2<float> *C );
00379 template GULAPI void CurvePoint(
00380 const double u, const int n, const int p, const Ptr< double >& U,
00381 const Ptr< hpoint2<double> >& Pw, point2<double> *C );
00382
00383 template GULAPI void CurvePoint(
00384 const float u, const int n, const int p, const Ptr< float >& U,
00385 const Ptr< point<float> >& Pw, point<float> *C );
00386 template GULAPI void CurvePoint(
00387 const double u, const int n, const int p, const Ptr< double >& U,
00388 const Ptr< point<double> >& Pw, point<double> *C );
00389 template GULAPI void CurvePoint(
00390 const float u, const int n, const int p, const Ptr< float >& U,
00391 const Ptr< point2<float> >& Pw, point2<float> *C );
00392 template GULAPI void CurvePoint(
00393 const double u, const int n, const int p, const Ptr< double >& U,
00394 const Ptr< point2<double> >& Pw, point2<double> *C );
00395
00396
00397
00398
00399
00400
00401 template< class T, class HP, class EP >
00402 GULAPI
00403 void SurfacePoint(
00404 const T u, const T v,
00405 const int nu, const int pu, const Ptr< T >& U,
00406 const int nv, const int pv, const Ptr< T >& V,
00407 const Ptr< Ptr< HP > >& Pw, EP *retS )
00408 {
00409 Ptr< T > Nu,Nv;
00410 int uspan,vspan,uind,vind,l,k;
00411 HP S,temp,v1;
00412
00413 Nu.reserve_place( reserve_stack(T,pu+1), pu+1 );
00414 Nv.reserve_place( reserve_stack(T,pv+1), pv+1 );
00415
00416 uspan = FindSpan( u, nu, pu, U );
00417 CalcBasisFunctions( u, uspan, pu, U, Nu );
00418
00419 vspan = FindSpan( v, nv, pv, V );
00420 CalcBasisFunctions( v, vspan, pv, V, Nv );
00421
00422 uind = uspan-pu;
00423 set( S, (T)0.0 );
00424 for( l = 0; l <= pv; l++ )
00425 {
00426 set( temp, (T)0.0 );
00427 vind = vspan - pv + l;
00428 for( k = 0; k <= pu; k++ )
00429 {
00430 v1 = Nu[k] * Pw[vind][uind+k];
00431
00432 temp = temp + v1;
00433 }
00434 v1 = Nv[l] * temp;
00435 S = S + v1;
00436 }
00437 *retS = euclid( S );
00438 }
00439
00440 template GULAPI void SurfacePoint(
00441 const float u, const float v,
00442 const int nu, const int pu, const Ptr< float >& U,
00443 const int nv, const int pv, const Ptr< float >& V,
00444 const Ptr< Ptr< hpoint<float> > >& Pw, point<float> *retS );
00445 template GULAPI void SurfacePoint(
00446 const double u, const double v,
00447 const int nu, const int pu, const Ptr< double >& U,
00448 const int nv, const int pv, const Ptr< double >& V,
00449 const Ptr< Ptr< hpoint<double> > >& Pw, point<double> *retS );
00450 template GULAPI void SurfacePoint(
00451 const float u, const float v,
00452 const int nu, const int pu, const Ptr< float >& U,
00453 const int nv, const int pv, const Ptr< float >& V,
00454 const Ptr< Ptr< hpoint1<float> > >& Pw, point1<float> *retS );
00455 template GULAPI void SurfacePoint(
00456 const double u, const double v,
00457 const int nu, const int pu, const Ptr< double >& U,
00458 const int nv, const int pv, const Ptr< double >& V,
00459 const Ptr< Ptr< hpoint1<double> > >& Pw, point1<double> *retS );
00460
00461 template GULAPI void SurfacePoint(
00462 const float u, const float v,
00463 const int nu, const int pu, const Ptr< float >& U,
00464 const int nv, const int pv, const Ptr< float >& V,
00465 const Ptr< Ptr< point<float> > >& Pw, point<float> *retS );
00466 template GULAPI void SurfacePoint(
00467 const double u, const double v,
00468 const int nu, const int pu, const Ptr< double >& U,
00469 const int nv, const int pv, const Ptr< double >& V,
00470 const Ptr< Ptr< point<double> > >& Pw, point<double> *retS );
00471 template GULAPI void SurfacePoint(
00472 const float u, const float v,
00473 const int nu, const int pu, const Ptr< float >& U,
00474 const int nv, const int pv, const Ptr< float >& V,
00475 const Ptr< Ptr< point1<float> > >& Pw, point1<float> *retS );
00476 template GULAPI void SurfacePoint(
00477 const double u, const double v,
00478 const int nu, const int pu, const Ptr< double >& U,
00479 const int nv, const int pv, const Ptr< double >& V,
00480 const Ptr< Ptr< point1<double> > >& Pw, point1<double> *retS );
00481
00482
00483
00484
00485
00486
00487
00488 template< class T, class HP, class EP >
00489 GULAPI
00490 void BezierSurfacePoint(
00491 const T u, const T v,
00492 const int pu, const Ptr< T >& U,
00493 const int pv, const Ptr< T >& V,
00494 const Ptr< Ptr< HP > >& Pw, EP *retS )
00495 {
00496 Ptr< T > Nu,Nv;
00497 int uspan,vspan,uind,vind,l,k;
00498 HP S,temp,v1;
00499
00500 Nu.reserve_place( reserve_stack(T,pu+1), pu+1 );
00501 Nv.reserve_place( reserve_stack(T,pv+1), pv+1 );
00502
00503 uspan = pu;
00504 CalcBasisFunctions( u, uspan, pu, U, Nu );
00505
00506 vspan = pv;
00507 CalcBasisFunctions( v, vspan, pv, V, Nv );
00508
00509 uind = uspan-pu;
00510 set( S, (T)0.0 );
00511 for( l = 0; l <= pv; l++ )
00512 {
00513 set( temp, (T)0.0 );
00514 vind = vspan - pv + l;
00515 for( k = 0; k <= pu; k++ )
00516 {
00517 v1 = Nu[k] * Pw[vind][uind+k];
00518
00519 temp = temp + v1;
00520 }
00521 v1 = Nv[l] * temp;
00522 S = S + v1;
00523 }
00524 *retS = euclid( S );
00525 }
00526
00527 template GULAPI void BezierSurfacePoint(
00528 const float u, const float v,
00529 const int pu, const Ptr< float >& U,
00530 const int pv, const Ptr< float >& V,
00531 const Ptr< Ptr< hpoint<float> > >& Pw, point<float> *retS );
00532 template GULAPI void BezierSurfacePoint(
00533 const double u, const double v,
00534 const int pu, const Ptr< double >& U,
00535 const int pv, const Ptr< double >& V,
00536 const Ptr< Ptr< hpoint<double> > >& Pw, point<double> *retS );
00537 template GULAPI void BezierSurfacePoint(
00538 const float u, const float v,
00539 const int pu, const Ptr< float >& U,
00540 const int pv, const Ptr< float >& V,
00541 const Ptr< Ptr< hpoint1<float> > >& Pw, point1<float> *retS );
00542 template GULAPI void BezierSurfacePoint(
00543 const double u, const double v,
00544 const int pu, const Ptr< double >& U,
00545 const int pv, const Ptr< double >& V,
00546 const Ptr< Ptr< hpoint1<double> > >& Pw, point1<double> *retS );
00547
00548 template GULAPI void BezierSurfacePoint(
00549 const float u, const float v,
00550 const int pu, const Ptr< float >& U,
00551 const int pv, const Ptr< float >& V,
00552 const Ptr< Ptr< point<float> > >& Pw, point<float> *retS );
00553 template GULAPI void BezierSurfacePoint(
00554 const double u, const double v,
00555 const int pu, const Ptr< double >& U,
00556 const int pv, const Ptr< double >& V,
00557 const Ptr< Ptr< point<double> > >& Pw, point<double> *retS );
00558 template GULAPI void BezierSurfacePoint(
00559 const float u, const float v,
00560 const int pu, const Ptr< float >& U,
00561 const int pv, const Ptr< float >& V,
00562 const Ptr< Ptr< point1<float> > >& Pw, point1<float> *retS );
00563 template GULAPI void BezierSurfacePoint(
00564 const double u, const double v,
00565 const int pu, const Ptr< double >& U,
00566 const int pv, const Ptr< double >& V,
00567 const Ptr< Ptr< point1<double> > >& Pw, point1<double> *retS );
00568
00569
00570
00571
00572 }
00573
00574
00575
00576