Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

gunu_refine2.cpp

Go to the documentation of this file.
00001 /* LIBGUL - Geometry Utility Library
00002  * Copyright (C) 1998-1999 Norbert Irmer
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Library General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Library General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Library General Public
00015  * License along with this library; if not, write to the
00016  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00017  * Boston, MA 02111-1307, USA.
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 #include "gunu_refine.h"
00028 
00029 namespace gunu {
00030 
00031 using gul::Ptr;
00032 using gul::point;
00033 using gul::hpoint;
00034 using gul::point2;
00035 using gul::hpoint2;
00036 using gul::point1;
00037 using gul::hpoint1;
00038 
00039 /*-------------------------------------------------------------------------*//**
00040   Inserts 'r'+1 knots given by the refinement vector 'X' into the U or 
00041   V knot vector of a surface (and calculates the changed control points).
00042   no validity checks are made, multiplicity of the inserted knots mustn't
00043   exceed the degree 'pu' or 'pv', memory for the new knot vectors 'Ubar' 
00044   and Vbar and the control point matrix 'Q' must be reserved by the caller:
00045   Ubar: nu+pu+2+r, Q: [nv]*[nu+1+r], if 'dir' == u_direction,
00046   Vbar: nv+pv+2+r, Q: [nv+1+r]*[nu], if 'dir' == v_direction                  */
00047 /*----------------------------------------------------------------------------*/
00048 template< class T, class HP >
00049 void RefineSurfaceV( 
00050        int nu, int pu, const Ptr<T>& U, int nv, int pv, const Ptr<T>& V, 
00051        const Ptr< Ptr< HP > >& P, const Ptr<T>& X, int r,
00052        Ptr<T>& Ubar, Ptr<T>& Vbar, Ptr< Ptr< HP > >& Q )
00053 {
00054   int i,j,k,l,m,a,b,ind,col;
00055   T alfa;
00056   
00057   m = nv + pv + 1;
00058   
00059 /* ----- search minimum and maximum+1 knot span  a and b ----------- */
00060   a = FindSpan( X[0], nv, pv, V );
00061   b = FindSpan( X[r], nv, pv, V );
00062   b = b + 1;
00063   
00064 /* ------ initialise Vbar ------------------------------------------ */
00065   for( j = 0; j <= a; j++ )
00066     Vbar[j] = V[j];
00067   for( j = b+pv; j <= m; j++ )
00068     Vbar[j+r+1] = V[j];    
00069   
00070 /* ------ copy U to Ubar ------------------------------------------- */
00071   for( j = 0; j <= nu + pu + 1; j++ )
00072     Ubar[j] = U[j];
00073       
00074 /* ------ copy unchanged control points ------------------------ */
00075   for( col = 0; col <= nu; col++ )
00076   {
00077     for( k = 0; k <= a-pv; k++ )
00078       Q[k][col] = P[k][col];
00079     for( k = b-1; k <= nv; k++ )
00080       Q[k+r+1][col] = P[k][col];
00081   }      
00082 
00083   i = b+pv-1;
00084   k = b+pv+r;
00085   for( j = r; j >= 0; j-- )
00086   {
00087     while( (X[j] <= V[i]) && (i > a) )
00088     {
00089 /*--------- calc Vbar ------------------------------------------------- */
00090       Vbar[k] = V[i];
00091 
00092       for( col = 0; col <= nu; col++ )
00093         Q[k-pv-1][col] = P[i-pv-1][col];
00094       k -= 1;
00095       i -= 1;
00096     }   
00097     for( col = 0; col <= nu; col++ )
00098       Q[k-pv-1][col] = Q[k-pv][col];
00099      
00100     for( l = 1; l <= pv; l++ )
00101     {
00102       ind = k-pv+l;
00103       alfa = Vbar[k+l] - X[j];
00104       if( fabs(alfa) == 0.0 )
00105         for( col = 0; col <= nu; col++ )
00106           Q[ind-1][col] = Q[ind][col];
00107       else
00108       {
00109         alfa = alfa / ( Vbar[k+l] - V[i-pv+l] );             
00110         for( col = 0; col <= nu; col++ )
00111         {
00112           Q[ind-1][col] = alfa * Q[ind-1][col] + ((T)1 - alfa) * Q[ind][col];
00113         }
00114       }
00115     }      
00116     Vbar[k] = X[j];
00117     k--;
00118   }  
00119 }                            
00120 // template instantiation
00121 template void RefineSurfaceV( 
00122   int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V, 
00123   const Ptr< Ptr< point<float> > >& P, const Ptr<float>& X, int r,
00124   Ptr<float>& Ubar, Ptr<float>& Vbar, Ptr< Ptr< point<float> > >& Q );
00125 template void RefineSurfaceV( 
00126   int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V, 
00127   const Ptr< Ptr< hpoint<float> > >& P, const Ptr<float>& X, int r,
00128   Ptr<float>& Ubar, Ptr<float>& Vbar, Ptr< Ptr< hpoint<float> > >& Q );
00129 template void RefineSurfaceV( 
00130   int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V, 
00131   const Ptr< Ptr< point1<float> > >& P, const Ptr<float>& X, int r,
00132   Ptr<float>& Ubar, Ptr<float>& Vbar, Ptr< Ptr< point1<float> > >& Q );
00133 template void RefineSurfaceV( 
00134   int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V, 
00135   const Ptr< Ptr< hpoint1<float> > >& P, const Ptr<float>& X, int r,
00136   Ptr<float>& Ubar, Ptr<float>& Vbar, Ptr< Ptr< hpoint1<float> > >& Q );
00137 
00138 template void RefineSurfaceV( 
00139   int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V, 
00140   const Ptr< Ptr< point<double> > >& P, const Ptr<double>& X, int r,
00141   Ptr<double>& Ubar, Ptr<double>& Vbar, Ptr< Ptr< point<double> > >& Q );
00142 template void RefineSurfaceV( 
00143   int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V, 
00144   const Ptr< Ptr< hpoint<double> > >& P, const Ptr<double>& X, int r,
00145   Ptr<double>& Ubar, Ptr<double>& Vbar, Ptr< Ptr< hpoint<double> > >& Q );
00146 template void RefineSurfaceV( 
00147   int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V, 
00148   const Ptr< Ptr< point1<double> > >& P, const Ptr<double>& X, int r,
00149   Ptr<double>& Ubar, Ptr<double>& Vbar, Ptr< Ptr< point1<double> > >& Q );
00150 template void RefineSurfaceV( 
00151   int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V, 
00152   const Ptr< Ptr< hpoint1<double> > >& P, const Ptr<double>& X, int r,
00153   Ptr<double>& Ubar, Ptr<double>& Vbar, Ptr< Ptr< hpoint1<double> > >& Q );
00154 
00155 /*-------------------------------------------------------------------------*//**
00156  decompose a surface in u or v direction into its Bezier segments. 
00157  when for example decomposing in U-direction, the function returns
00158  a array containing bezier strips with [nv+1]*[pu+1] control point
00159  matrices, the function result is the number of created bezier segments       */ 
00160 /*----------------------------------------------------------------------------*/
00161 /* Example for decomposition in U-direction:
00162 
00163          -----------------------------------------> (U-direction)|
00164         |
00165         |  Bezier   : Bezier   : Bezier   :
00166         |  Stip     : Strip    : Strip : ...
00167 (nv)-   |  0        : 1        : 2        :
00168 rows    |           :          :          :
00169         |  <------> : <------> : <------> :
00170         |  (pu+1)-  : (pu+1)-  : (pu+1)-  :
00171         |  columns  : columns  : columns  :
00172         |           :          :          :
00173         |           :          :          :
00174         |           :          :          :
00175         V 
00176     (V-direction)
00177 */
00178 template< class T, class HP >
00179 void BezierDecomposeSurfaceV( 
00180               int nK, const Ptr<int>& K, const Ptr<int>& M,
00181               int nu, int pu, const Ptr<T>& U,
00182               int nv, int pv, const Ptr<T>& V,              
00183               const Ptr< Ptr<HP> >& Pw,
00184               Ptr< Ptr< Ptr<HP> > > *retQw )
00185 {
00186   int m,a,b,nb,i,j,mult,save,r,s,k,col;
00187   T numer,alpha;
00188   Ptr<T> alphas;
00189   Ptr< Ptr< Ptr<HP> > > Qw;
00190 
00191   Qw.reserve_pool(nK);
00192   for( nb = 0; nb < nK; nb++ )
00193   {
00194     Qw[nb].reserve_pool(pv+1);
00195     for( i = 0; i <= pv; i++ )
00196       Qw[nb][i].reserve_pool(nu+1);
00197   }  
00198   
00199   alphas.reserve_pool(pv+1);
00200 
00201   m = nv + pv + 1;
00202   a = pv;
00203   b = pv+1;
00204   nb = 0;
00205   
00206   // initialize first Bezier segment
00207   for( i = 0; i <= pv; i++ )
00208     for( col = 0; col <= nu; col++ )
00209       Qw[nb][i][col] = Pw[i][col];
00210     
00211   while( nb < nK )
00212   {
00213     b = K[nb];
00214     mult = M[nb];
00215 
00216     if( mult < pv )
00217     {
00218       numer = V[b] - V[a];                           /* numerator of alpha */
00219 
00220       for( j = pv; j > mult; j-- )                   /* j = p,..,p-r */
00221       alphas[j-mult-1] = numer / (V[a+j] - V[a]);
00222 
00223       r = pv - mult;                             /* insert knot r-times */
00224       
00225       for( j = 1; j <= r; j++ )
00226       {
00227         save = r - j;
00228         
00229         s = mult + j;
00230         
00231         for( k = pv; k >= s; k-- )
00232         {
00233           alpha = alphas[k-s];
00234 
00235           for( col = 0; col <= nu; col++ )
00236           {
00237             Qw[nb][k][col] = 
00238                    alpha * Qw[nb][k][col] + ((T)1 - alpha) * Qw[nb][k-1][col];
00239           }
00240         }
00241         if( b < m )                 
00242         {
00243           for( col = 0; col <= nu; col ++ )
00244             Qw[nb+1][save][col] = Qw[nb][pv][col];
00245         }      
00246       }        
00247     }        
00248     nb = nb + 1;                          /* next Bezier segment */  
00249 
00250     if( nb < nK )
00251     {
00252       for( i = pv - mult; i <= pv; i++ )
00253         for( col = 0; col <= nu; col++ )
00254           Qw[nb][i][col] = Pw[b-pv+i][col];
00255        a = b;
00256     }
00257   }
00258 
00259   *retQw = Qw;
00260 }
00261 // template instantiation
00262 template void BezierDecomposeSurfaceV( 
00263     int nK, const Ptr<int>& K, const Ptr<int>& M,
00264     int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V,              
00265     const Ptr< Ptr< point<float> > >& Pw,
00266     Ptr< Ptr< Ptr< point<float> > > > *retQw );
00267 template void BezierDecomposeSurfaceV( 
00268     int nK, const Ptr<int>& K, const Ptr<int>& M,
00269     int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V,              
00270     const Ptr< Ptr< hpoint<float> > >& Pw,
00271     Ptr< Ptr< Ptr< hpoint<float> > > > *retQw );
00272 template void BezierDecomposeSurfaceV( 
00273     int nK, const Ptr<int>& K, const Ptr<int>& M,
00274     int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V,              
00275     const Ptr< Ptr< point1<float> > >& Pw,
00276     Ptr< Ptr< Ptr< point1<float> > > > *retQw );
00277 template void BezierDecomposeSurfaceV( 
00278     int nK, const Ptr<int>& K, const Ptr<int>& M,
00279     int nu, int pu, const Ptr<float>& U, int nv, int pv, const Ptr<float>& V,              
00280     const Ptr< Ptr< hpoint1<float> > >& Pw,
00281     Ptr< Ptr< Ptr< hpoint1<float> > > > *retQw );
00282 
00283 template void BezierDecomposeSurfaceV( 
00284     int nK, const Ptr<int>& K, const Ptr<int>& M,
00285     int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V,              
00286     const Ptr< Ptr< point<double> > >& Pw,
00287     Ptr< Ptr< Ptr< point<double> > > > *retQw );
00288 template void BezierDecomposeSurfaceV( 
00289     int nK, const Ptr<int>& K, const Ptr<int>& M,
00290     int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V,              
00291     const Ptr< Ptr< hpoint<double> > >& Pw,
00292     Ptr< Ptr< Ptr< hpoint<double> > > > *retQw );
00293 template void BezierDecomposeSurfaceV( 
00294     int nK, const Ptr<int>& K, const Ptr<int>& M,
00295     int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V,              
00296     const Ptr< Ptr< point1<double> > >& Pw,
00297     Ptr< Ptr< Ptr< point1<double> > > > *retQw );
00298 template void BezierDecomposeSurfaceV( 
00299     int nK, const Ptr<int>& K, const Ptr<int>& M,
00300     int nu, int pu, const Ptr<double>& U, int nv, int pv, const Ptr<double>& V,              
00301     const Ptr< Ptr< hpoint1<double> > >& Pw,
00302     Ptr< Ptr< Ptr< hpoint1<double> > > > *retQw );
00303 
00304 }

Generated on Mon Jan 21 04:17:42 2002 for GUL 0.6 - Geometry Utility Library by doxygen1.2.13.1 written by Dimitri van Heesch, © 1997-2001